# Path: awscfncli2/config/deployment.py
# class StackKey(namedtuple('StackKey', sorted(StackDefaults.STACK_KEY))):
# 
#     @property
#     def qualified_name(self):
#         return '.'.join([self.StageKey, self.StackKey])
# 
#     @staticmethod
#     def from_dict(**params):
#         result = copy.deepcopy(StackDefaults.STACK_KEY)
#         _extends(result, **params)
#         return StackKey(**result)
# 
# class StackDeployment(
#     namedtuple('StackDeployment', 'stack_key, metadata, profile, parameters')):
#     pass
# 
# class StackMetadata(
#     namedtuple('StackMetadata', sorted(StackDefaults.STACK_METADATA))):
#     @staticmethod
#     def from_dict(**params):
#         result = copy.deepcopy(StackDefaults.STACK_METADATA)
#         _extends(result, **params)
#         return StackMetadata(**result)
# 
# class StackProfile(
#     namedtuple('StackMetadata', sorted(StackDefaults.STACK_PROFILE))):
#     @staticmethod
#     def from_dict(**params):
#         result = copy.deepcopy(StackDefaults.STACK_PROFILE)
#         _extends(result, **params)
#         return StackProfile(**result)
# 
# class StackParameters(
#     namedtuple('StackParameters', sorted(StackDefaults.STACK_PARAMETERS))):
#     @staticmethod
#     def from_dict(**params):
#         result = copy.deepcopy(StackDefaults.STACK_PARAMETERS)
#         _extends(result, **params)
#         return StackParameters(**result)
# 
#     def find_references(self):
#         # TODO Need refactor to reduce duplicated ParameterTemplate construction
#         return find_references(self._asdict())
# 
#     def substitute_references(self, **args):
#         return substitute_references(self._asdict(), **args)
# 
# class Deployment(object):
# 
#     def __init__(self):
#         self._index = dict()
# 
#     def add_stack(self, stage_key, stack_key, stack):
#         key = (stage_key, stack_key)
#         self._index[key] = stack
# 
#     def get_stack(self, stage_key, stack_key):
#         key = (stage_key, stack_key)
#         return self._index.get(key)
# 
#     def get_stacks(self, stage_key):
#         return list(k1 for (k1, k2) in self._index if k1 == stage_key)
# 
#     def query_stacks(self, stage_pattern='*', stack_pattern='*'):
#         """Find all stack config matching stage/stack patterns
#         """
#         result = list()
#         for (k1, k2) in self._index:
#             if fnmatch.fnmatchcase(k1, stage_pattern) \
#                     and fnmatch.fnmatchcase(k2, stack_pattern):
#                 result.append(self._index[(k1, k2)])
# 
#         result.sort(key=lambda stack: stack.metadata.Order)
# 
#         return result
# 
# Path: awscfncli2/config/schema.py
# def load_schema(version):
#     filename = os.path.join(
#         get_schema_path(), 'schema_v{0}.json'.format(version))
#     with open(filename, 'r') as fp:
#         return json.load(fp)
# 
# Path: awscfncli2/config/template.py
# def find_references(params):
#     dumps = json.dumps(params)
#     references = []
#     for match in _Template.pattern.findall(dumps):
#         if match and match[2]:
#             references.append(match[2])
#     return references


import copy
import os
import jsonschema
import six
from .deployment import StackKey, StackDeployment, StackMetadata, StackProfile, \
    StackParameters, Deployment
from .schema import load_schema
from .template import find_references


def load_format(version):
    if version == 3:
        return FormatV3
    elif version == 2:
        return FormatV2
    elif version == 1 or version is None:
        return FormatV1
    else:
        raise FormatError('Unspported config version {}'.format(version))


class ConfigFormat(object):
    VERSION = None

    def validate(self, config):
        raise NotImplementedError

    def parse(self, config):
        raise NotImplementedError


class FormatV1(ConfigFormat):
    VERSION = '1.0.0'

    def __init__(self, **context):
        self._context = context

    def validate(self, config):

# Path: awscfncli2/config/deployment.py
# class StackKey(namedtuple('StackKey', sorted(StackDefaults.STACK_KEY))):
# 
#     @property
#     def qualified_name(self):
#         return '.'.join([self.StageKey, self.StackKey])
# 
#     @staticmethod
#     def from_dict(**params):
#         result = copy.deepcopy(StackDefaults.STACK_KEY)
#         _extends(result, **params)
#         return StackKey(**result)
# 
# class StackDeployment(
#     namedtuple('StackDeployment', 'stack_key, metadata, profile, parameters')):
#     pass
# 
# class StackMetadata(
#     namedtuple('StackMetadata', sorted(StackDefaults.STACK_METADATA))):
#     @staticmethod
#     def from_dict(**params):
#         result = copy.deepcopy(StackDefaults.STACK_METADATA)
#         _extends(result, **params)
#         return StackMetadata(**result)
# 
# class StackProfile(
#     namedtuple('StackMetadata', sorted(StackDefaults.STACK_PROFILE))):
#     @staticmethod
#     def from_dict(**params):
#         result = copy.deepcopy(StackDefaults.STACK_PROFILE)
#         _extends(result, **params)
#         return StackProfile(**result)
# 
# class StackParameters(
#     namedtuple('StackParameters', sorted(StackDefaults.STACK_PARAMETERS))):
#     @staticmethod
#     def from_dict(**params):
#         result = copy.deepcopy(StackDefaults.STACK_PARAMETERS)
#         _extends(result, **params)
#         return StackParameters(**result)
# 
#     def find_references(self):
#         # TODO Need refactor to reduce duplicated ParameterTemplate construction
#         return find_references(self._asdict())
# 
#     def substitute_references(self, **args):
#         return substitute_references(self._asdict(), **args)
# 
# class Deployment(object):
# 
#     def __init__(self):
#         self._index = dict()
# 
#     def add_stack(self, stage_key, stack_key, stack):
#         key = (stage_key, stack_key)
#         self._index[key] = stack
# 
#     def get_stack(self, stage_key, stack_key):
#         key = (stage_key, stack_key)
#         return self._index.get(key)
# 
#     def get_stacks(self, stage_key):
#         return list(k1 for (k1, k2) in self._index if k1 == stage_key)
# 
#     def query_stacks(self, stage_pattern='*', stack_pattern='*'):
#         """Find all stack config matching stage/stack patterns
#         """
#         result = list()
#         for (k1, k2) in self._index:
#             if fnmatch.fnmatchcase(k1, stage_pattern) \
#                     and fnmatch.fnmatchcase(k2, stack_pattern):
#                 result.append(self._index[(k1, k2)])
# 
#         result.sort(key=lambda stack: stack.metadata.Order)
# 
#         return result
# 
# Path: awscfncli2/config/schema.py
# def load_schema(version):
#     filename = os.path.join(
#         get_schema_path(), 'schema_v{0}.json'.format(version))
#     with open(filename, 'r') as fp:
#         return json.load(fp)
# 
# Path: awscfncli2/config/template.py
# def find_references(params):
#     dumps = json.dumps(params)
#     references = []
#     for match in _Template.pattern.findall(dumps):
#         if match and match[2]:
#             references.append(match[2])
#     return references


# Path: awscfncli2/config/formats.py
import copy
import os
import jsonschema
import six
from .deployment import StackKey, StackDeployment, StackMetadata, StackProfile, \
    StackParameters, Deployment
from .schema import load_schema
from .template import find_references



def load_format(version):
    if version == 3:
        return FormatV3
    elif version == 2:
        return FormatV2
    elif version == 1 or version is None:
        return FormatV1
    else:
        raise FormatError('Unspported config version {}'.format(version))


class ConfigFormat(object):
    VERSION = None

    def validate(self, config):
        raise NotImplementedError

    def parse(self, config):
        raise NotImplementedError


class FormatV1(ConfigFormat):
    VERSION = '1.0.0'

    def __init__(self, **context):
        self._context = context

    def validate(self, config):

        schema = load_schema(str(self.VERSION))