# Copyright (c) 2021 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("//build_overrides/build.gni")
import("//build_overrides/chip.gni")
import("${chip_root}/build/chip/chip_codegen.gni")
import("${chip_root}/src/platform/python.gni")

import("${chip_root}/src/lib/core/core.gni")

_app_root = get_path_info(".", "abspath")

_zap_cluster_list_script = get_path_info("zap_cluster_list.py", "abspath")

# Defines a source_set for CHIP data model.
#
# Arguments:
#  zap_pregenerated_dir
#    Path to the ZAP "gen" dir.
#
#  zap_file
#    Path to the ZAP input file.
#
#  idl
#    Path to the .matter IDL corresponding to the zap file. This is for
#    dependencies on build-time code generation.
#
# Forwards all the remaining variables to the source_set.
#
template("chip_data_model") {
  _data_model_name = target_name

  if (defined(invoker.idl)) {
    _idl = invoker.idl
  } else {
    # Assume that IDL name is the same as the zap file name, but instead of
    # '.zap' use '.matter' as extension. This is currently the case in the
    # sample apps, but may change in the future
    print("AUTO-DETECTING input matter IDL file.")
    _idl = string_replace(invoker.zap_file, ".zap", ".matter")
  }

  chip_codegen("${_data_model_name}_codegen") {
    input = _idl
    generator = "cpp-app"
    outputs = [ "app/PluginApplicationCallbacks.h" ]
  }

  config("${_data_model_name}_config") {
    include_dirs = []

    if (defined(invoker.zap_pregenerated_dir)) {
      include_dirs += [ "${invoker.zap_pregenerated_dir}/.." ]
    }
  }

  _use_default_im_dispatch = !defined(invoker.use_default_im_dispatch) ||
                             invoker.use_default_im_dispatch

  source_set(_data_model_name) {
    forward_variables_from(invoker,
                           "*",
                           [
                             "zap_pregenerated_dir",
                             "zap_file",
                             "is_server",
                           ])

    if (!defined(sources)) {
      sources = []
    }

    sources += get_target_outputs(":${_data_model_name}_codegen")

    sources += [
      "${_app_root}/clusters/barrier-control-server/barrier-control-server.h",
      "${_app_root}/clusters/basic/basic.h",
      "${_app_root}/clusters/color-control-server/color-control-server.h",
      "${_app_root}/clusters/door-lock-server/door-lock-server.h",
      "${_app_root}/clusters/groups-server/groups-server.h",
      "${_app_root}/clusters/identify-server/identify-server.h",
      "${_app_root}/clusters/level-control/level-control.h",
      "${_app_root}/clusters/on-off-server/on-off-server.h",
      "${_app_root}/clusters/scenes/scenes-tokens.h",
      "${_app_root}/clusters/scenes/scenes.h",
      "${_app_root}/util/DataModelHandler.cpp",
      "${_app_root}/util/af-event.cpp",
      "${_app_root}/util/attribute-size-util.cpp",
      "${_app_root}/util/attribute-storage.cpp",
      "${_app_root}/util/attribute-table.cpp",
      "${_app_root}/util/binding-table.cpp",
      "${_app_root}/util/binding-table.h",
      "${_app_root}/util/ember-compatibility-functions.cpp",
      "${_app_root}/util/ember-print.cpp",
      "${_app_root}/util/error-mapping.cpp",
      "${_app_root}/util/generic-callback-stubs.cpp",
      "${_app_root}/util/message.cpp",
      "${_app_root}/util/privilege-storage.cpp",
      "${_app_root}/util/util.cpp",
      "${chip_root}/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp",
    ]

    if (defined(invoker.zap_file)) {
      _zap_path = rebase_path(invoker.zap_file, root_build_dir)
      _script_path = rebase_path(_zap_cluster_list_script, root_build_dir)
      _script_args = [ "--zap_file=" + _zap_path ]

      _cluster_sources = exec_script("${build_root}/gn_run_binary.py",
                                     [ _script_path ] + _script_args,
                                     "list lines",
                                     [ invoker.zap_file ])
    }

    foreach(cluster, _cluster_sources) {
      if (cluster == "door-lock-server") {
        sources += [
          "${_app_root}/clusters/${cluster}/door-lock-server-callback.cpp",
          "${_app_root}/clusters/${cluster}/door-lock-server.cpp",
        ]
      } else if (cluster == "mode-select-server") {
        sources += [
          "${_app_root}/clusters/${cluster}/${cluster}.cpp",
          "${_app_root}/clusters/${cluster}/supported-modes-manager.h",
        ]
      } else if (cluster == "application-launcher-server") {
        sources += [
          "${_app_root}/app-platform/ContentApp.cpp",
          "${_app_root}/app-platform/ContentAppPlatform.cpp",
          "${_app_root}/clusters/${cluster}/${cluster}.cpp",
        ]
      } else if (cluster == "ota-requestor") {
        sources += [
          # TODO - align name of folder ?
          "${_app_root}/clusters/${cluster}/${cluster}-server.cpp",
          "${_app_root}/clusters/${cluster}/BDXDownloader.cpp",
          "${_app_root}/clusters/${cluster}/BDXDownloader.h",
          "${_app_root}/clusters/${cluster}/DefaultOTARequestor.cpp",
          "${_app_root}/clusters/${cluster}/DefaultOTARequestorDriver.cpp",
          "${_app_root}/clusters/${cluster}/DefaultOTARequestorStorage.cpp",
          "${_app_root}/clusters/${cluster}/DefaultOTARequestorStorage.h",
          "${_app_root}/clusters/${cluster}/DefaultOTARequestorUserConsent.h",
          "${_app_root}/clusters/${cluster}/ExtendedOTARequestorDriver.cpp",
          "${_app_root}/clusters/${cluster}/OTARequestorStorage.h",
          "${_app_root}/clusters/${cluster}/OTATestEventTriggerDelegate.cpp",
          "${_app_root}/clusters/${cluster}/OTATestEventTriggerDelegate.h",
        ]
      } else if (cluster == "bindings") {
        sources += [
          "${_app_root}/clusters/${cluster}/${cluster}.cpp",
          "${_app_root}/clusters/${cluster}/BindingManager.cpp",
          "${_app_root}/clusters/${cluster}/BindingManager.h",
          "${_app_root}/clusters/${cluster}/PendingNotificationMap.cpp",
          "${_app_root}/clusters/${cluster}/PendingNotificationMap.h",
        ]
      } else {
        sources += [ "${_app_root}/clusters/${cluster}/${cluster}.cpp" ]
      }
    }

    if (defined(invoker.zap_pregenerated_dir)) {
      sources += [ "${invoker.zap_pregenerated_dir}/callback-stub.cpp" ]

      if (chip_controller) {
        sources += [ "${invoker.zap_pregenerated_dir}/CHIPClusters.h" ]
      }

      if (_use_default_im_dispatch) {
        sources +=
            [ "${invoker.zap_pregenerated_dir}/IMClusterCommandHandler.cpp" ]
      }
    }

    if (!defined(public_deps)) {
      public_deps = []
    }

    public_deps += [
      ":${_data_model_name}_codegen",
      "${chip_root}/src/app",
      "${chip_root}/src/app/common:cluster-objects",
      "${chip_root}/src/controller",
      "${chip_root}/src/lib/core",
      "${chip_root}/src/lib/support",
      "${chip_root}/src/protocols/secure_channel",
    ]

    if (defined(invoker.is_server)) {
      public_deps += [ "${chip_root}/src/app/server" ]
    }

    if (!defined(cflags)) {
      cflags = []
    }

    cflags += [ "-Wconversion" ]

    if (!defined(public_configs)) {
      public_configs = []
    }

    public_configs += [ ":${_data_model_name}_config" ]
  }
}
