import unittest
from unittest import mock
import moto
import pytest
import json
import os
from zenyatta.common.util import (update_aws_resource_variable, get_aws_resource_variable,
                                  parse_config_file, run_command, check_response, dump_to_file,
                                  dump_to_json)
from zenyatta.common.errors import ZenyattaError

RESOURCES = {'ec2': [], 'ebs': [], 'rds': []}
CONTEXT = {'role_arn': 'arn:aws:iam::465369119046:role/airflow'}
CFG = {'ec2': {}, 'emr': {}, 'redis': {}}
RESPONSE = [{'ResponseMetadata': {'HTTPStatusCode': 200}}, {'ResponseMetadata': {'HTTPStatusCode': 403}}]


class UtilTestCase(unittest.TestCase):

    @mock.patch('zenyatta.common.util.Variable.get', return_value=RESOURCES)
    def test_get_aws_variable(self, var_mock):
        instance_id = 'dummy_instance_id'
        RESOURCES['ec2'].append(instance_id)
        rtn = get_aws_resource_variable("dummy key", 'ec2')
        assert instance_id == rtn[0]

    @mock.patch('zenyatta.common.util.Variable.set', return_value=RESOURCES)
    @mock.patch('zenyatta.common.util.Variable.get', return_value=RESOURCES)
    def test_update_aws_variable(self, get_mock, set_mock):
        ebs_id = 'dummy_vol_id'
        RESOURCES['ebs'] = ebs_id
        rtn = update_aws_resource_variable("dummy key", 'ebs', ebs_id, False)
        assert ebs_id == rtn['ebs']

    def test_parse_config_file(self):
        with self.assertRaises(ZenyattaError):
            cfg = parse_config_file("whatever")

    @mock.patch('zenyatta.common.util.yaml.safe_load', return_value=CFG)
    @mock.patch('zenyatta.common.util.open', return_value=True)
    @mock.patch('zenyatta.common.util.os.path.isfile', return_value=True)
    def test_parse_config(self, isfile_mock, open_mock, yaml_mock):
        cfg = parse_config_file("whatever")
        assert isfile_mock.called is True
        assert open_mock.called is True

    def test_run_command(self):
        cmd = ["echo", "hello"]
        rtn = run_command(cmd)
        assert rtn.decode().split('\n')[0] == "hello"

    def test_check_response(self):
        rtn = check_response(RESPONSE[0])
        assert rtn is True
        with self.assertRaises(ZenyattaError):
            check_response(RESPONSE[1])

    def test_dump_json(self):
        file_name = "dummy.json"
        json_block = {}
        json_block['foo'] = 'bar'
        if os.path.isfile(file_name):
            os.remove(file_name)
        rtn = dump_to_json(json_block, file_name)
        assert rtn == file_name
        with open(file_name, 'r') as f:
            jobj = json.load(f)
            assert jobj == json_block
        os.remove(file_name)


if __name__ == '__main__':
    unittest.main()
