#!/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)

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

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

    if type(actual) == BasicInteger:
        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,
            }
        )
