import unittest
import json
import os
from jsonschema import ValidationError

from mcp.config_validator import MCPConfigValidator

class MCPConfigValidatorTest(unittest.TestCase):

    def setUp(self):
        # Create temporary files for testing
        self.schema_path = 'test_schema.json'
        self.config_path = 'test_config.json'
        self.invalid_config_path = 'test_invalid_config.json'

        # Create a valid schema
        self.valid_schema = {
            "type": "object",
            "properties": {
                "name": {"type": "string"},
                "version": {"type": "number", "minimum": 1.0}
            },
            "required": ["name", "version"]
        }
        with open(self.schema_path, 'w') as f:
            json.dump(self.valid_schema, f)

        # Create a valid config
        self.valid_config = {
            "name": "MyMCP",
            "version": 1.2
        }
        with open(self.config_path, 'w') as f:
            json.dump(self.valid_config, f)

        # Create an invalid config (missing required field)
        self.invalid_config = {
            "version": 0.8
        }
        with open(self.invalid_config_path, 'w') as f:
            json.dump(self.invalid_config, f)

    def tearDown(self):
        # Remove the temporary files
        os.remove(self.schema_path)
        os.remove(self.config_path)
        os.remove(self.invalid_config_path)

    def test_load_schema(self):
        validator = MCPConfigValidator(self.schema_path)
        self.assertEqual(validator.schema, self.valid_schema)

    def test_load_schema_file_not_found(self):
        with self.assertRaises(FileNotFoundError):
            MCPConfigValidator("non_existent_schema.json")

    def test_load_schema_invalid_json(self):
        with open("invalid_schema.json", "w") as f:
            f.write("invalid json")
        with self.assertRaises(json.JSONDecodeError):
            MCPConfigValidator("invalid_schema.json")
        os.remove("invalid_schema.json")

    def test_validate_config_valid(self):
        validator = MCPConfigValidator(self.schema_path)
        errors = validator.validate_config(self.config_path)
        self.assertEqual(len(errors), 0)
        self.assertTrue(validator.is_valid(self.config_path))

    def test_validate_config_invalid(self):
        validator = MCPConfigValidator(self.schema_path)
        errors = validator.validate_config(self.invalid_config_path)
        self.assertGreater(len(errors), 0)  # Expect at least one error
        self.assertFalse(validator.is_valid(self.invalid_config_path))
        self.assertIn("Validation error: 'name' is a required property at ", errors[0])

    def test_validate_config_file_not_found(self):
        validator = MCPConfigValidator(self.schema_path)
        with self.assertRaises(FileNotFoundError):
            validator.validate_config("non_existent_config.json")

    def test_validate_config_invalid_json(self):
        with open("invalid_config.json", "w") as f:
            f.write("invalid json")
        validator = MCPConfigValidator(self.schema_path)
        with self.assertRaises(json.JSONDecodeError):
            validator.validate_config("invalid_config.json")
        os.remove("invalid_config.json")


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