# 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}/reporting/reporting.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" ]
  }
}
