from openapi_spec_validator import openapi_v30_spec_validator
from openapi_spec_validator.readers import read_from_filename
from openapi_schema_validator import validate
from jsonschema.validators import RefResolver
import unittest
import json
import os


SCHEMA_DIR = "project/soar/swagger.json"
MOCK_DATA_DIR = "examples/"


class SchemaError(Exception):
    """
    Test config specs of swagger.json for projects
    """

    def __init__(self, exception_type, message):
        self.type = exception_type
        self.message = message
        super().__init__(self.message)


class TestSpecs(unittest.TestCase):
    def test_swagger_specs(self):
        """
        Test specs (swagger.json generated from generate_schema_config.py)
        """
        schema, spec_url = read_from_filename("tests/fixtures/swagger.json")
        self.assertIsNotNone(openapi_v30_spec_validator.validate(schema))


class TestAllMessageExamples(unittest.TestCase):
    def test_schema_specs(self):
        """
        Test specs (swagger.json generated from generate_schema_config.py)
        """
        schema_ref = open(SCHEMA_DIR)
        schema = json.load(schema_ref)
        schema_ref.close()

        partner_dir_list = os.listdir(MOCK_DATA_DIR)

        for partner in partner_dir_list:
            if not partner.endswith(".py"):
                print("TEST: Partner is %s" % partner.upper())
                message_list = os.listdir(os.path.join(MOCK_DATA_DIR, partner))
                for message_type in message_list:
                    if message_type.endswith(".json"):
                        print("Testing %s now..." % message_type)

                        f = open(
                            os.path.join(
                                MOCK_DATA_DIR,
                                partner,
                                message_type,
                            )
                        )
                        mock_message = json.load(f)
                        ref_resolver = RefResolver.from_schema(schema)

                        self.assertIsNone(
                            validate(
                                mock_message,
                                schema["components"]["schemas"]["MESSAGE"],
                                resolver=ref_resolver,
                            )
                        )
                        f.close()
                        print("Done.")

        schema_ref.close()


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