#!/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 enum
import logging
import re

from idl.generators import CodeGenerator, GeneratorStorage
from idl.matter_idl_types import Idl, Field, Attribute, Cluster, ClusterSide
from idl import matter_idl_types
from idl.generators.types import (ParseDataType, BasicString, BasicInteger, FundamentalType,
                                  IdlType, IdlEnumType, IdlBitmapType, TypeLookupContext)
from typing import Union, List, Set


def camel_to_const(s):
    return re.sub("([a-z])([A-Z])", lambda y: y.group(1) + "_" + y.group(2), s).upper()


def create_lookup_context(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 get_field_info(definition: Field, cluster: Cluster, idl: Idl):
    context = create_lookup_context(idl, cluster)
    actual = ParseDataType(definition.data_type, context)

    orig = actual
    is_enum = type(actual) == IdlEnumType

    if type(actual) == IdlEnumType:
        actual = actual.base_type
    elif type(actual) == IdlBitmapType:
        actual = actual.base_type

    if type(actual) == BasicString:
        return 'OctetString', 'char', actual.max_length, \
            'ZCL_%s_ATTRIBUTE_TYPE' % orig.idl_name.upper()

    if type(actual) == BasicInteger:
        name = orig.idl_name.upper()
        if is_enum:
            name = actual.idl_name.upper()
        ty = "int%d_t" % actual.power_of_two_bits
        if not actual.is_signed:
            ty = "u" + ty
        return "", ty, actual.byte_count, "ZCL_%s_ATTRIBUTE_TYPE" % name
    if type(actual) == FundamentalType:
        if actual == FundamentalType.BOOL:
            return "", "bool", 1, "ZCL_BOOLEAN_ATTRIBUTE_TYPE"
        if actual == FundamentalType.FLOAT:
            return "", "float", 4, "ZCL_SINGLE_ATTRIBUTE_TYPE"
        if actual == FundamentalType.DOUBLE:
            return "", "double", 8, "ZCL_DOUBLE_ATTRIBUTE_TYPE"
        logging.warn('Unknown fundamental type: %r' % actual)
        return None
    if type(actual) == IdlType:
        return '', actual.idl_name, 'sizeof(%s)' % actual.idl_name, \
            'ZCL_STRUCT_ATTRIBUTE_TYPE'
    logging.warn('Unknown type: %r' % actual)
    return None


def get_raw_size_and_type(attr: Attribute, cluster: Cluster, idl: Idl):
    container, cType, size, matterType = get_field_info(attr.definition, cluster, idl)
    if attr.definition.is_list:
        return 'ZCL_ARRAY_ATTRIBUTE_TYPE, {}'.format(size)
    return '{}, {}'.format(matterType, size)


def get_field_type(definition: Field, cluster: Cluster, idl: Idl):
    container, cType, size, matterType = get_field_info(definition, cluster, idl)
    if container == 'OctetString':
        return 'std::string'
    if definition.is_list:
        cType = 'std::vector<{}>'.format(cType)
    if definition.is_nullable:
        cType = '::chip::app::DataModel::Nullable<{}>'.format(cType)
    if definition.is_nullable:
        cType = '::chip::Optional<{}>'.format(cType)
    return cType


def get_attr_type(attr: Attribute, cluster: Cluster, idl: Idl):
    return get_field_type(attr.definition, cluster, idl)


def get_attr_init(attr: Attribute, cluster: Cluster, idl: Idl):
    if attr.definition.name == 'clusterRevision':
        return ', ZCL_' + camel_to_const(cluster.name) + '_CLUSTER_REVISION'
    return ''


def get_attr_mask(attr: Attribute, cluster: Cluster, idl: Idl):
    masks = []
    if attr.is_writable:
        masks.append('ATTRIBUTE_MASK_WRITABLE')
    if masks:
        return ' | '.join(masks)
    return '0'


def get_dynamic_endpoint(idl: Idl):
    for ep in idl.endpoints:
        if ep.number == 2:
            return ep


def is_dynamic_cluster(cluster: Cluster, idl: Idl):
    ep = get_dynamic_endpoint(idl)
    if not ep:
        return True
    for c in ep.server_clusters:
        if cluster.name == c.name:
            return True
    return False


class BridgeGenerator(CodeGenerator):
    """
    Generation of bridge cpp code for matter.
    """

    def __init__(self, storage: GeneratorStorage, idl: Idl):
        """
        Inintialization is specific for cpp generation and will add
        filters as required by the cpp .jinja templates to function.
        """
        super().__init__(storage, idl)

        self.jinja_env.filters['getType'] = get_attr_type
        self.jinja_env.filters['getRawSizeAndType'] = get_raw_size_and_type
        self.jinja_env.filters['getField'] = get_field_type
        self.jinja_env.filters['getMask'] = get_attr_mask
        self.jinja_env.filters['getInit'] = get_attr_init
        self.jinja_env.filters['dynamicCluster'] = is_dynamic_cluster
        # constcase will transform ID to I_D which is not what we want
        # instead make the requirement a transition from lower to upper
        self.jinja_env.filters['cameltoconst'] = camel_to_const

    def internal_render_all(self):
        """
        Renders C++
        """
        for cluster in self.idl.clusters:
            if not is_dynamic_cluster(cluster, self.idl):
                continue

            if cluster.side != ClusterSide.SERVER:
                output_file_name = "bridge/%sServer.h" % cluster.name
            else:
                output_file_name = "bridge/%s.h" % cluster.name

            self.internal_render_one_output(
                template_path="bridge/BridgeClustersCpp.jinja",
                output_file_name=output_file_name,
                vars={
                    'cluster': cluster,
                    'idl': self.idl,
                }
            )

        self.internal_render_one_output(
            template_path="bridge/BridgeClustersCommon.jinja",
            output_file_name="bridge/BridgeClustersImpl.h",
            vars={
                'clusters': self.idl.clusters,
                'idl': self.idl,
            }
        )

        self.internal_render_one_output(
            template_path="bridge/BridgeClustersGlobalStructs.jinja",
            output_file_name="bridge/BridgeGlobalStructs.h",
            vars={
                'idl': self.idl,
                'structs': self.idl.structs,
            }
        )
