#!/usr/bin/env python
# Copyright (c) 2022 Project CHIP Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import dataclasses
import enum
import logging
import os
from typing import List, Optional, Set

from matter_idl.generators import CodeGenerator, GeneratorStorage
from matter_idl.generators.types import (BasicInteger, BasicString, FundamentalType, IdlBitmapType, IdlEnumType, IdlType,
                                         ParseDataType, TypeLookupContext)
from matter_idl.matter_idl_types import (Attribute, Cluster, ClusterSide, Command, DataType, Field, FieldQuality, Idl, Struct,
                                         StructTag)
from stringcase import capitalcase


@dataclasses.dataclass
class GenerateTarget:
    template: str
    output_name: str


@dataclasses.dataclass
class GlobalType:
    name: str       # java name
    cpp_type: str  # underlying type


# types that java should see globally
_GLOBAL_TYPES = [
    GlobalType("Boolean", "bool"),
    GlobalType("CharString", "const chip::CharSpan"),
    GlobalType("Double", "double"),
    GlobalType("Float", "float"),
    GlobalType("Int8s", "int8_t"),
    GlobalType("Int8u", "uint8_t"),
    GlobalType("Int16s", "int16_t"),
    GlobalType("Int16u", "uint16_t"),
    GlobalType("Int32s", "int32_t"),
    GlobalType("Int32u", "uint32_t"),
    GlobalType("Int64s", "int64_t"),
    GlobalType("Int64u", "uint64_t"),
    GlobalType("OctetString", "const chip::ByteSpan"),
]


def _UnderlyingType(field: Field, context: TypeLookupContext) -> Optional[str]:
    actual = ParseDataType(field.data_type, context)
    if isinstance(actual, (IdlEnumType, IdlBitmapType)):
        actual = actual.base_type

    if isinstance(actual, BasicString):
        if actual.is_binary:
            return 'OctetString'
        else:
            return 'CharString'
    elif isinstance(actual, BasicInteger):
        if actual.is_signed:
            return "Int{}s".format(actual.power_of_two_bits)
        else:
            return "Int{}u".format(actual.power_of_two_bits)
    elif isinstance(actual, FundamentalType):
        if actual == FundamentalType.BOOL:
            return 'Boolean'
        elif actual == FundamentalType.FLOAT:
            return 'Float'
        elif actual == FundamentalType.DOUBLE:
            return 'Double'
        else:
            logging.warn('Unknown fundamental type: %r' % actual)

    return None


def FieldToGlobalName(field: Field, context: TypeLookupContext) -> Optional[str]:
    """Global names are used for generic callbacks shared across
    all clusters (e.g. for bool/float/uint32 and similar)
    """
    if field.is_list:
        return None  # lists are always specific per cluster

    if FieldQuality.NULLABLE & field.qualities:
        return None

    return _UnderlyingType(field, context)


# Based on atomicType in ZAP:
#  src-electron/generator/matter/app/zap-templates/common/override.js
_KNOWN_DECODABLE_TYPES = {
    'action_id': 'chip::ActionId',
    'attrib_id': 'chip::AttributeId',
    'cluster_id': 'chip::ClusterId',
    'command_id': 'chip::CommandId',
    'data_ver': 'chip::DataVersion',
    'devtype_id': 'chip::DeviceTypeId',
    'endpoint_no': 'chip::EndpointId',
    'eui64': 'chip::NodeId',
    'event_id': 'chip::EventId',
    'event_no': 'chip::EventNumber',
    'fabric_id': 'chip::FabricId',
    'fabric_idx': 'chip::FabricIndex',
    'fabric_idx': 'chip::FabricIndex',
    'field_id': 'chip::FieldId',
    'group_id': 'chip::GroupId',
    'node_id': 'chip::NodeId',
    'percent': 'chip::Percent',
    'percent100ths': 'chip::Percent100ths',
    'transaction_id': 'chip::TransactionId',
    'vendor_id': 'chip::VendorId',

    # non-named enums
    'enum8': 'uint8_t',
    'enum16': 'uint16_t',
    'enum32': 'uint32_t',
    'enum64': 'uint64_t',
}


def _CppType(field: Field, context: TypeLookupContext) -> str:
    if field.data_type.name.lower() in _KNOWN_DECODABLE_TYPES:
        return _KNOWN_DECODABLE_TYPES[field.data_type.name.lower()]

    actual = ParseDataType(field.data_type, context)
    if isinstance(actual, BasicString):
        if actual.is_binary:
            return 'chip::ByteSpan'
        else:
            return 'chip::CharSpan'
    elif isinstance(actual, BasicInteger):
        if actual.is_signed:
            return "int{}_t".format(actual.power_of_two_bits)
        else:
            return "uint{}_t".format(actual.power_of_two_bits)
    elif isinstance(actual, FundamentalType):
        if actual == FundamentalType.BOOL:
            return 'bool'
        elif actual == FundamentalType.FLOAT:
            return 'float'
        elif actual == FundamentalType.DOUBLE:
            return 'double'
        else:
            logging.warn('Unknown fundamental type: %r' % actual)
    elif isinstance(actual, IdlType):
        return f"chip::app::Clusters::{context.cluster.name}::Structs::{field.data_type.name}::DecodableType"
    elif isinstance(actual, IdlBitmapType):
        return f"chip::BitMask<chip::app::Clusters::{context.cluster.name}::{field.data_type.name}>"

    # Handles IdlEnumType
    return f"chip::app::Clusters::{context.cluster.name}::{field.data_type.name}"


def DecodableJniType(field: Field, context: TypeLookupContext) -> str:
    actual = _CppType(field, context)

    needsConstRef = False
    if field.is_list:
        needsConstRef = True
        actual = f"chip::app::DataModel::DecodableList<{actual}>"

    if field.is_nullable:
        needsConstRef = True
        actual = f"chip::app::DataModel::Nullable<{actual}>"

    if needsConstRef:
        actual = f"const {actual} &"

    return actual


def GlobalNameToJavaName(name: str) -> str:
    if name in {'Int8u', 'Int8s', 'Int16u', 'Int16s'}:
        return 'Integer'

    if name.startswith('Int'):
        return 'Long'

    # Double/Float/Booleans/CharString/OctetString
    return name


def DelegatedCallbackName(attr: Attribute, context: TypeLookupContext) -> str:
    """
    Figure out what callback name to use for delegate callback construction.
    """
    global_name = FieldToGlobalName(attr.definition, context)

    if global_name:
        return 'Delegated{}AttributeCallback'.format(GlobalNameToJavaName(global_name))

    return 'Delegated{}Cluster{}AttributeCallback'.format(context.cluster.name, capitalcase(attr.definition.name))


def ChipClustersCallbackName(attr: Attribute, context: TypeLookupContext) -> str:
    """
    Figure out what callback name to use when building a ChipCluster.*AttributeCallback
    in java codegen.
    """
    global_name = FieldToGlobalName(attr.definition, context)

    if global_name:
        return 'ChipClusters.{}AttributeCallback'.format(GlobalNameToJavaName(global_name))

    return 'ChipClusters.{}Cluster.{}AttributeCallback'.format(context.cluster.name, capitalcase(attr.definition.name))


def CallbackName(attr: Attribute, context: TypeLookupContext) -> str:
    """
    Figure out what callback name to use when a variable requires a read callback.

    These are split into native types, like Boolean/Float/Double/CharString, where
    one callback type can support anything.

    For specific types (e.g. A struct) codegen will generate its own callback name
    specific to that type.
    """
    global_name = FieldToGlobalName(attr.definition, context)

    if global_name:
        return 'CHIP{}AttributeCallback'.format(capitalcase(global_name))

    return 'CHIP{}{}AttributeCallback'.format(
        capitalcase(context.cluster.name),
        capitalcase(attr.definition.name)
    )


def CommandCallbackName(command: Command, cluster: Cluster):
    if command.output_param.lower() == 'defaultsuccess':
        return 'DefaultSuccess'
    return '{}Cluster{}'.format(cluster.name, command.output_param)


def attributesWithSupportedCallback(attrs, context: TypeLookupContext):
    for attr in attrs:
        # Attributes will be generated for all types
        # except non-list structures
        if not attr.definition.is_list:
            underlying = ParseDataType(attr.definition.data_type, context)
            if isinstance(underlying, IdlType):
                continue

        yield attr


def _IsUsingGlobalCallback(field: Field, context: TypeLookupContext):
    """Test to determine if the data type of a field can use one of
    the global callbacks (i.e. it is a basic double/integer/bool etc.)
    """
    if field.is_list:
        return False

    if field.is_nullable:
        return False

    return field.data_type.name in {
        "boolean",
        "single",
        "double",
        "int8s",
        "int8u",
        "int16s",
        "int16u",
        "int24s",
        "int24u",
        "int32s",
        "int32u",
        "int40s",
        "int40u",
        "int48s",
        "int48u",
        "int56s",
        "int56u",
        "int64s",
        "int64u",
        "enum8",
        "enum16",
        "enum32",
        "enum64",
        "bitmap8",
        "bitmap16",
        "bitmap32",
        "bitmap64",
        "char_string",
        "long_char_string",
        "octet_string",
        "long_octet_string",
    }


def NamedFilter(choices: List, name: str):
    for choice in choices:
        if choice.name == name:
            return choice
    raise Exception("No item named %s in %r" % (name, choices))


def ToBoxedJavaType(field: Field):
    if field.is_optional:
        return 'jobject'
    elif field.data_type.name.lower() in ['octet_string', 'long_octet_string']:
        return 'jbyteArray'
    elif field.data_type.name.lower() in ['char_string', 'long_char_string']:
        return 'jstring'
    else:
        return 'jobject'


def LowercaseFirst(name: str) -> str:
    """
    Change the first letter of a string to lowercase as long as the 2nd
    letter is not uppercase.

    Can be used for variable naming, eg insider structures, codegen will
    call things "Foo foo" (notice variable name is lowercase).
    """
    if len(name) > 1 and name[1].lower() != name[1]:
        # Odd workaround: PAKEVerifier should not become pAKEVerifier
        return name
    return name[0].lower() + name[1:]


class EncodableValueAttr(enum.Enum):
    LIST = enum.auto()
    NULLABLE = enum.auto()
    OPTIONAL = enum.auto()


class EncodableValue:
    """
    Contains helpers for encoding values, specifically lookups
    for optionality, lists and recursive data type lookups within
    the IDL and cluster

    Intended use is to be able to:
      - derive types (see clone and without_* methods) such that codegen
        can implement things like 'if x != null { treat non-null x}'
      - Java specific conversions: get boxed types and JNI string signautes
        for the underlying types.
    """

    def __init__(self, context: TypeLookupContext, data_type: DataType, attrs: Set[EncodableValueAttr]):
        self.context = context
        self.data_type = data_type
        self.attrs = attrs

    @property
    def is_nullable(self):
        return EncodableValueAttr.NULLABLE in self.attrs

    @property
    def is_optional(self):
        return EncodableValueAttr.OPTIONAL in self.attrs

    @property
    def is_list(self):
        return EncodableValueAttr.LIST in self.attrs

    @property
    def is_octet_string(self):
        return self.data_type.name.lower() in ['octet_string', 'long_octet_string']

    @property
    def is_char_string(self):
        return self.data_type.name.lower() in ['char_string', 'long_char_string']

    @property
    def is_struct(self):
        return self.context.is_struct_type(self.data_type.name)

    @property
    def is_enum(self):
        return self.context.is_enum_type(self.data_type.name)

    @property
    def is_bitmap(self):
        return self.context.is_bitmap_type(self.data_type.name)

    @property
    def is_untyped_bitmap(self):
        return self.context.is_untyped_bitmap_type(self.data_type.name)

    def clone(self):
        return EncodableValue(self.context, self.data_type, self.attrs)

    def without_nullable(self):
        result = self.clone()
        result.attrs.remove(EncodableValueAttr.NULLABLE)
        return result

    def without_optional(self):
        result = self.clone()
        result.attrs.remove(EncodableValueAttr.OPTIONAL)
        return result

    def without_list(self):
        result = self.clone()
        result.attrs.remove(EncodableValueAttr.LIST)
        return result

    def get_underlying_struct(self):
        s = self.context.find_struct(self.data_type.name)
        if not s:
            raise Exception("Struct %s not found" % self.data_type.name)
        return s

    def get_underlying_enum(self):
        e = self.context.find_enum(self.data_type.name)
        if not e:
            raise Exception("Enum %s not found" % self.data_type.name)
        return e

    @property
    def boxed_java_type(self):
        t = ParseDataType(self.data_type, self.context)

        if isinstance(t, FundamentalType):
            if t == FundamentalType.BOOL:
                return "Boolean"
            elif t == FundamentalType.FLOAT:
                return "Float"
            elif t == FundamentalType.DOUBLE:
                return "Double"
            else:
                raise Exception("Unknown fundamental type")
        elif isinstance(t, BasicInteger):
            # the >= 3 will include int24_t to be considered "long"
            if t.byte_count >= 3:
                return "Long"
            else:
                return "Integer"
        elif isinstance(t, BasicString):
            if t.is_binary:
                return "byte[]"
            else:
                return "String"
        elif isinstance(t, IdlEnumType):
            if t.base_type.byte_count >= 3:
                return "Long"
            else:
                return "Integer"
        elif isinstance(t, IdlBitmapType):
            if t.base_type.byte_count >= 3:
                return "Long"
            else:
                return "Integer"
        else:
            return "Object"

    @property
    def boxed_java_signature(self):
        # Optional takes precedence over list - Optional<ArrayList> compiles down to just java.util.Optional.
        if self.is_optional:
            return "Ljava/util/Optional;"

        if self.is_list:
            return "Ljava/util/ArrayList;"

        t = ParseDataType(self.data_type, self.context)

        if isinstance(t, FundamentalType):
            if t == FundamentalType.BOOL:
                return "Ljava/lang/Boolean;"
            elif t == FundamentalType.FLOAT:
                return "Ljava/lang/Float;"
            elif t == FundamentalType.DOUBLE:
                return "Ljava/lang/Double;"
            else:
                raise Exception("Unknown fundamental type")
        elif isinstance(t, BasicInteger):
            if t.byte_count >= 3:
                return "Ljava/lang/Long;"
            else:
                return "Ljava/lang/Integer;"
        elif isinstance(t, BasicString):
            if t.is_binary:
                return "[B"
            else:
                return "Ljava/lang/String;"
        elif isinstance(t, IdlEnumType):
            if t.base_type.byte_count >= 3:
                return "Ljava/lang/Long;"
            else:
                return "Ljava/lang/Integer;"
        elif isinstance(t, IdlBitmapType):
            if t.base_type.byte_count >= 3:
                return "Ljava/lang/Long;"
            else:
                return "Ljava/lang/Integer;"
        else:
            return "Lchip/devicecontroller/ChipStructs${}Cluster{};".format(self.context.cluster.name, self.data_type.name)


def EncodableValueFrom(field: Field, context: TypeLookupContext) -> EncodableValue:
    """
    Filter to convert a standard field to an EncodableValue.

    This converts the AST information (field name/info + lookup context) into
    a java-generator specific wrapper that can be manipulated and
    queried for properties like java native name or JNI string signature.
    """
    attrs = set()

    if field.is_optional:
        attrs.add(EncodableValueAttr.OPTIONAL)

    if field.is_nullable:
        attrs.add(EncodableValueAttr.NULLABLE)

    if field.is_list:
        attrs.add(EncodableValueAttr.LIST)

    return EncodableValue(context, field.data_type, attrs)


def CreateLookupContext(idl: Idl, cluster: Cluster) -> TypeLookupContext:
    """
    A filter to mark a lookup context to be within a specific cluster.

    This is used to specify how structure/enum/other names are looked up.
    Generally one looks up within the specific cluster then if cluster does
    not contain a definition, we loop at global namespacing.
    """
    return TypeLookupContext(idl, cluster)


def CanGenerateSubscribe(attr: Attribute, lookup: TypeLookupContext) -> bool:
    """
    Filter that returns if an attribute can be subscribed to.

    Uses the given attribute and the lookupContext to figure out the attribute
    type.
    """
    # For backwards compatibility, we do not subscribe to structs
    # (although list of structs is ok ...)
    if attr.definition.is_list:
        return True

    return not lookup.is_struct_type(attr.definition.data_type.name)


def IsResponseStruct(s: Struct) -> bool:
    return s.tag == StructTag.RESPONSE


class __JavaCodeGenerator(CodeGenerator):
    """
    Code generation for java-specific files.

    Registers filters used by all java generators.
    """

    def __init__(self, storage: GeneratorStorage, idl: Idl, **kargs):
        """
        Inintialization is specific for java generation and will add
        filters as required by the java .jinja templates to function.
        """
        super().__init__(storage, idl, fs_loader_searchpath=os.path.dirname(__file__))

        self.jinja_env.filters['attributesWithCallback'] = attributesWithSupportedCallback
        self.jinja_env.filters['callbackName'] = CallbackName
        self.jinja_env.filters['chipClustersCallbackName'] = ChipClustersCallbackName
        self.jinja_env.filters['delegatedCallbackName'] = DelegatedCallbackName
        self.jinja_env.filters['commandCallbackName'] = CommandCallbackName
        self.jinja_env.filters['named'] = NamedFilter
        self.jinja_env.filters['toBoxedJavaType'] = ToBoxedJavaType
        self.jinja_env.filters['lowercaseFirst'] = LowercaseFirst
        self.jinja_env.filters['asEncodable'] = EncodableValueFrom
        self.jinja_env.filters['createLookupContext'] = CreateLookupContext
        self.jinja_env.filters['canGenerateSubscribe'] = CanGenerateSubscribe
        self.jinja_env.filters['decodableJniType'] = DecodableJniType

        self.jinja_env.tests['is_response_struct'] = IsResponseStruct
        self.jinja_env.tests['is_using_global_callback'] = _IsUsingGlobalCallback


class JavaJNIGenerator(__JavaCodeGenerator):
    """Generates JNI java files (i.e. C++ source/headers)."""

    def __init__(self, *args, **kargs):
        super().__init__(*args, **kargs)

    def internal_render_all(self):
        """
        Renders .CPP files required for JNI support.
        """

        large_targets = [
            GenerateTarget(template="CHIPCallbackTypes.jinja",
                           output_name="jni/CHIPCallbackTypes.h"),
            GenerateTarget(template="CHIPReadCallbacks_h.jinja",
                           output_name="jni/CHIPReadCallbacks.h")
        ]

        for target in large_targets:
            self.internal_render_one_output(
                template_path=target.template,
                output_file_name=target.output_name,
                vars={
                    'idl': self.idl,
                    'clientClusters': [c for c in self.idl.clusters if c.side == ClusterSide.CLIENT],
                    'globalTypes': _GLOBAL_TYPES,
                }
            )

        cluster_targets = [
            GenerateTarget(template="ChipClustersRead.jinja",
                           output_name="jni/{cluster_name}Client-ReadImpl.cpp"),
            GenerateTarget(template="ChipClustersCpp.jinja",
                           output_name="jni/{cluster_name}Client-InvokeSubscribeImpl.cpp"),
        ]

        self.internal_render_one_output(
            template_path="CHIPCallbackTypes.jinja",
            output_file_name="jni/CHIPCallbackTypes.h",
            vars={
                'idl': self.idl,
                'clientClusters': [c for c in self.idl.clusters if c.side == ClusterSide.CLIENT],
            }
        )

        # Every cluster has its own impl, to avoid
        # very large compilations (running out of RAM)
        for cluster in self.idl.clusters:
            if cluster.side != ClusterSide.CLIENT:
                continue

            for target in cluster_targets:
                self.internal_render_one_output(
                    template_path=target.template,
                    output_file_name=target.output_name.format(
                        cluster_name=cluster.name),
                    vars={
                        'cluster': cluster,
                        'typeLookup': TypeLookupContext(self.idl, cluster),
                        'globalTypes': _GLOBAL_TYPES,
                    }
                )


class JavaClassGenerator(__JavaCodeGenerator):
    """Generates .java files """

    def __init__(self, *args, **kargs):
        super().__init__(*args, **kargs)

    def internal_render_all(self):
        """
        Renders .java files required for java matter support
        """

        clientClusters = [
            c for c in self.idl.clusters if c.side == ClusterSide.CLIENT]

        self.internal_render_one_output(
            template_path="ClusterReadMapping.jinja",
            output_file_name="java/chip/devicecontroller/ClusterReadMapping.java",
            vars={
                'idl': self.idl,
                'clientClusters': clientClusters,
            }
        )

        self.internal_render_one_output(
            template_path="ClusterWriteMapping.jinja",
            output_file_name="java/chip/devicecontroller/ClusterWriteMapping.java",
            vars={
                'idl': self.idl,
                'clientClusters': clientClusters,
            }
        )

        self.internal_render_one_output(
            template_path="ClusterIDMapping.jinja",
            output_file_name="java/chip/devicecontroller/ClusterIDMapping.java",
            vars={
                'idl': self.idl,
                'clientClusters': clientClusters,
            }
        )
