# ----------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License
# ----------------------------------------------------------------------
"""Contains the TypeInfo object"""

import os

import CommonEnvironment
from CommonEnvironment import Interface

# ----------------------------------------------------------------------
_script_fullpath                            = CommonEnvironment.ThisFullpath()
_script_dir, _script_name                   = os.path.split(_script_fullpath)
#  ----------------------------------------------------------------------

# ----------------------------------------------------------------------
class TypeInfo(Interface.Interface):
    """Creates constructs that are useful when generating test code for a specific type"""

    # ----------------------------------------------------------------------
    # |
    # |  Public Types
    # |
    # ----------------------------------------------------------------------
    class Type(object):
        # ----------------------------------------------------------------------
        def __init__(self, type, name):
            self.Type                       = type
            self.Name                       = name

        # ----------------------------------------------------------------------
        def __repr__(self):
            return CommonEnvironment.ObjectReprImpl(self)

    # ----------------------------------------------------------------------
    class Result(object):
        """Result information about a type when it is used in various scenarios."""

        # ----------------------------------------------------------------------
        def __init__(
            self,
            vector_result_type,
            transform_vars,
            append_result_statement,
            destroy_args=None,
            destroy_inline=None,
            destroy_var_name=None,
        ):
            self.VectorResultType           = vector_result_type
            self.TransformVars              = transform_vars
            self.AppendResultStatement      = append_result_statement
            self.DestroyArgs                = destroy_args
            self.DestroyInline              = destroy_inline

            if destroy_var_name and destroy_inline:
                raise Exception("'destroy_var_name' should only be provided when 'destroy_inline' is False")

            self.DestroyVarName             = destroy_var_name

        # ----------------------------------------------------------------------
        def __repr__(self):
            return CommonEnvironment.ObjectReprImpl(self)

    # ----------------------------------------------------------------------
    # |
    # |  Public Properties
    # |
    # ----------------------------------------------------------------------
    @Interface.abstractproperty
    def TypeName(self):
        """Name of the type"""
        raise Exception("Abstract property")

    @Interface.abstractproperty
    def CppType(self):
        """C++ type"""
        raise Exception("Abstract property")

    # ----------------------------------------------------------------------
    # |
    # |  Public Methods
    # |
    # ----------------------------------------------------------------------
    def __init__(
        self,
        custom_structs=None,
        custom_enums=None,
        is_optional=False,
        member_type=None,
        create_type_info_func=None,
    ):
        self.CustomStructs                  = custom_structs
        self.CustomEnums                    = custom_enums
        self.IsOptional                     = is_optional

    # ----------------------------------------------------------------------
    def __repr__(self):
        return CommonEnvironment.ObjectReprImpl(self)

    # ----------------------------------------------------------------------
    @Interface.extensionmethod
    @staticmethod
    def CreateHelperMethods(output_stream):
        """Write any helper methods that are necessary to process the type"""
        pass

    # ----------------------------------------------------------------------
    @Interface.extensionmethod
    @staticmethod
    def GetPrefixContent():
        """Return a string that contains content that should be placed at the beginning of the generated file"""

        # No content is generated by default
        return None

    # ----------------------------------------------------------------------
    @Interface.abstractmethod
    def GetTransformInputArgs(
        self,
        input_name="input",
    ):
        """\
        Returns information about the type when used to create transformer-related tests.
        """
        raise Exception("Abstract method")

    # ----------------------------------------------------------------------
    @Interface.abstractmethod
    def GetTransformInputBufferArgs(
        self,
        input_name="input",
    ):
        """\
        Returns information about the type when used as a buffer to create transformer-related tests.
        """
        raise Exception("Abstract method")

    # ----------------------------------------------------------------------
    @Interface.abstractmethod
    def GetOutputInfo(
        self,
        invocation_template,
        result_name="result",
    ):
        """\
        Returns information about the type when used to create output info.
        """
        raise Exception("Abstract method")
