# 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("//build_overrides/openthread.gni")
import("//build_overrides/qpg_sdk.gni")

import("${build_root}/config/defaults.gni")
import("${chip_root}/src/platform/device.gni")
import("${qpg_sdk_build_root}/qpg_executable.gni")
import("${qpg_sdk_build_root}/qpg_sdk.gni")

# declares chip_build_libshell = false
import("${chip_root}/src/lib/lib.gni")

# declares chip_enable_pw_rpc = false
import("${chip_root}/examples/common/pigweed/pigweed_rpcs.gni")
if (chip_enable_pw_rpc) {
  import("//build_overrides/pigweed.gni")
  import("$dir_pw_build/target_types.gni")
}

assert(current_os == "freertos")

qpg_project_dir = "${chip_root}/examples/light-switch-app/qpg"
examples_plat_dir = "${chip_root}/examples/platform/qpg"

qpg_sdk("sdk") {
  include_dirs = [
    "${chip_root}/src/platform/qpg",
    "${examples_plat_dir}",
    "${qpg_project_dir}/include",
  ]

  defines = [ "PW_RPC_ENABLED=${chip_enable_pw_rpc}" ]
}

qpg_executable("light_switch_app") {
  output_name = "chip-${qpg_target_ic}-light-switch-example.out"

  sources = [
    "${chip_root}/src/app/clusters/general-diagnostics-server/GenericFaultTestEventTriggerHandler.cpp",
    "${examples_plat_dir}/app/main.cpp",
    "${examples_plat_dir}/ota/ota.cpp",
    "src/AppTask.cpp",
    "src/SwitchManager.cpp",
    "src/ZclCallbacks.cpp",
    "src/binding-handler.cpp",
  ]

  deps = [
    ":sdk",
    "${chip_root}/examples/light-switch-app/qpg/zap/",
    "${chip_root}/examples/providers:device_info_provider",
    "${chip_root}/src/lib",
    "${chip_root}/src/platform/logging:default",
    "${chip_root}/src/setup_payload",
    "${chip_root}/third_party/openthread/platforms:libopenthread-platform",
    "${chip_root}/third_party/openthread/platforms:libopenthread-platform-utils",
    "${chip_root}/third_party/qpg_sdk:qpg_switch_factorydata_lib",
    "${chip_root}/third_party/qpg_sdk:qpg_switch_firmwaredata_lib",
  ]

  if (chip_openthread_ftd) {
    deps += [ "${chip_root}/third_party/openthread/repo:libopenthread-ftd" ]
  } else {
    deps += [ "${chip_root}/third_party/openthread/repo:libopenthread-mtd" ]
  }

  include_dirs = [
    "include",
    "${examples_plat_dir}/ota",
  ]

  defines = []

  if (chip_enable_pw_rpc) {
    defines += [
      "PW_RPC_ATTRIBUTE_SERVICE=1",
      "PW_RPC_BUTTON_SERVICE=1",
      "PW_RPC_DEVICE_SERVICE=1",
      "PW_RPC_LOCKING_SERVICE=1",
    ]

    sources += [
      "${chip_root}/examples/common/pigweed/RpcService.cpp",
      "${chip_root}/examples/common/pigweed/qpg/PigweedLoggerMutex.cpp",
      "${examples_plat_dir}/PigweedLogger.cpp",
      "${examples_plat_dir}/Rpc.cpp",
      "${examples_plat_dir}/uart.c",
    ]

    deps += [
      "$dir_pw_hdlc:default_addresses",
      "$dir_pw_hdlc:rpc_channel_output",
      "$dir_pw_stream:sys_io_stream",
      "${chip_root}/config/qpg/lib/pw_rpc:pw_rpc",
      "${chip_root}/examples/common/pigweed:attributes_service.nanopb_rpc",
      "${chip_root}/examples/common/pigweed:button_service.nanopb_rpc",
      "${chip_root}/examples/common/pigweed:device_service.nanopb_rpc",
      "${chip_root}/examples/common/pigweed:locking_service.nanopb_rpc",
      "${examples_plat_dir}/pw_sys_io:pw_sys_io_qpg",
    ]

    deps += pw_build_LINK_DEPS

    include_dirs += [
      "${chip_root}/examples/common",
      "${chip_root}/examples/common/pigweed/qpg",
    ]
  } else {
    # The below gives compiler erros in pigweed, therefore it is only enabled
    # when rpc is not
    cflags = [ "-Wconversion" ]
  }

  if (chip_build_libshell) {
    deps += [ "${examples_plat_dir}:qpg-matter-shell" ]
  } else {
    if (chip_openthread_ftd) {
      deps +=
          [ "${chip_root}/third_party/openthread/repo:libopenthread-cli-ftd" ]
    } else {
      deps +=
          [ "${chip_root}/third_party/openthread/repo:libopenthread-cli-mtd" ]
    }
  }

  ldscript = "${qpg_sdk_root}/Libraries/Qorvo/QorvoStack/gen/QorvoStack_${qpg_target_ic}${qpg_flavour}/QorvoStack_${qpg_target_ic}${qpg_flavour}.ld"

  inputs = [ ldscript ]

  ldflags = [ "-T" + rebase_path(ldscript, root_build_dir) ]

  output_dir = root_out_dir
}

group("qpg") {
  deps = [ ":light_switch_app" ]
}

group("default") {
  deps = [ ":qpg" ]
}
