/*
 *   Copyright (c) 2023 Project CHIP Authors
 *   All rights reserved.
 *
 *   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.
 *
 */
package com.matter.controller.commands.pairing

import chip.devicecontroller.ChipDeviceController
import chip.devicecontroller.ICDDeviceInfo
import chip.devicecontroller.ICDRegistrationInfo
import chip.devicecontroller.NetworkCredentials
import com.matter.controller.commands.common.CredentialsIssuer
import com.matter.controller.commands.common.IPAddress
import com.matter.controller.commands.common.MatterCommand
import java.net.InetAddress
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicInteger
import java.util.concurrent.atomic.AtomicLong
import java.util.logging.Level
import java.util.logging.Logger

abstract class PairingCommand(
  controller: ChipDeviceController,
  commandName: String,
  credsIssuer: CredentialsIssuer?,
  private val pairingMode: PairingModeType = PairingModeType.NONE,
  private val networkType: PairingNetworkType = PairingNetworkType.NONE,
  private val filterType: DiscoveryFilterType = DiscoveryFilterType.NONE
) : MatterCommand(controller, credsIssuer, commandName), ChipDeviceController.CompletionListener {
  private val remoteAddr: IPAddress = IPAddress(InetAddress.getByName("::1"))
  private val nodeId = AtomicLong()
  private val discoveryFilterCode = AtomicLong()
  private val timeoutMillis = AtomicLong()
  private val discoverOnce = AtomicBoolean()
  private val useOnlyOnNetworkDiscovery = AtomicBoolean()
  private val remotePort = AtomicInteger()
  private val discriminator = AtomicInteger()
  private val setupPINCode = AtomicLong()
  private val operationalDataset = StringBuffer()
  private val ssid = StringBuffer()
  private val password = StringBuffer()
  private val onboardingPayload = StringBuffer()
  private val discoveryFilterInstanceName = StringBuffer()

  init {
    addArgument("node-id", 0, Long.MAX_VALUE, nodeId, null, false)

    when (networkType) {
      PairingNetworkType.NONE -> {}
      PairingNetworkType.WIFI -> {
        addArgument("ssid", ssid, null, false)
        addArgument("password", password, null, false)
      }
      PairingNetworkType.THREAD ->
        addArgument("operationalDataset", operationalDataset, null, false)
    }

    when (pairingMode) {
      PairingModeType.NONE -> {}
      PairingModeType.CODE,
      PairingModeType.CODE_PASE_ONLY -> {
        addArgument("payload", onboardingPayload, null, false)
        addArgument("discover-once", discoverOnce, null, true)
        addArgument("use-only-onnetwork-discovery", useOnlyOnNetworkDiscovery, null, true)
      }
      PairingModeType.ADDRESS_PASE_ONLY -> {
        addArgument("setup-pin-code", 0, 134217727, setupPINCode, null, false)
        addArgument("device-remote-ip", remoteAddr, false)
        addArgument("device-remote-port", 0.toShort(), Short.MAX_VALUE, remotePort, null, false)
      }
      PairingModeType.BLE -> {
        addArgument("setup-pin-code", 0, 134217727, setupPINCode, null, false)
        addArgument("discriminator", 0.toShort(), 4096.toShort(), discriminator, null, false)
      }
      PairingModeType.ON_NETWORK ->
        addArgument("setup-pin-code", 0, 134217727, setupPINCode, null, false)
      PairingModeType.SOFT_AP -> {
        addArgument("setup-pin-code", 0, 134217727, setupPINCode, null, false)
        addArgument("discriminator", 0.toShort(), 4096.toShort(), discriminator, null, false)
        addArgument("device-remote-ip", remoteAddr, false)
        addArgument("device-remote-port", 0.toShort(), Short.MAX_VALUE, remotePort, null, false)
      }
      PairingModeType.ALREADY_DISCOVERED -> {
        addArgument("setup-pin-code", 0, 134217727, setupPINCode, null, false)
        addArgument("device-remote-ip", remoteAddr, false)
        addArgument("device-remote-port", 0.toShort(), Short.MAX_VALUE, remotePort, null, false)
      }
    }

    when (filterType) {
      DiscoveryFilterType.NONE -> {}
      DiscoveryFilterType.SHORT_DISCRIMINATOR,
      DiscoveryFilterType.LONG_DISCRIMINATOR ->
        addArgument("discriminator", 0.toShort(), 4096.toShort(), discriminator, null, false)
      DiscoveryFilterType.VENDOR_ID ->
        addArgument("vendor-id", 1.toShort(), Short.MAX_VALUE, discoveryFilterCode, null, false)
      DiscoveryFilterType.COMPRESSED_FABRIC_ID ->
        addArgument("fabric-id", 0L, Long.MAX_VALUE, discoveryFilterCode, null, false)
      DiscoveryFilterType.COMMISSIONING_MODE,
      DiscoveryFilterType.COMMISSIONER -> {}
      DiscoveryFilterType.DEVICE_TYPE ->
        addArgument("device-type", 0.toShort(), Short.MAX_VALUE, discoveryFilterCode, null, false)
      DiscoveryFilterType.INSTANCE_NAME ->
        addArgument("name", discoveryFilterInstanceName, null, false)
    }

    addArgument("timeout", 0L, Long.MAX_VALUE, timeoutMillis, null, false)
  }

  override fun onConnectDeviceComplete() {
    logger.log(Level.INFO, "onConnectDeviceComplete")
  }

  override fun onStatusUpdate(status: Int) {
    logger.log(Level.INFO, "onStatusUpdate with status: $status")
  }

  override fun onPairingComplete(errorCode: Long) {
    logger.log(Level.INFO, "onPairingComplete with error code: $errorCode")
    if (errorCode != 0L) {
      setFailure("onPairingComplete failure")
    }
  }

  override fun onPairingDeleted(errorCode: Long) {
    logger.log(Level.INFO, "onPairingDeleted with error code: $errorCode")
  }

  override fun onCommissioningComplete(nodeId: Long, errorCode: Long) {
    logger.log(Level.INFO, "onCommissioningComplete with error code: $errorCode")
    if (errorCode == 0L) {
      setSuccess()
    } else {
      setFailure("onCommissioningComplete failure")
    }
  }

  override fun onReadCommissioningInfo(
    vendorId: Int,
    productId: Int,
    wifiEndpointId: Int,
    threadEndpointId: Int
  ) {
    logger.log(Level.INFO, "onReadCommissioningInfo")
  }

  override fun onCommissioningStatusUpdate(nodeId: Long, stage: String?, errorCode: Long) {
    logger.log(Level.INFO, "onCommissioningStatusUpdate")
  }

  override fun onNotifyChipConnectionClosed() {
    logger.log(Level.INFO, "onNotifyChipConnectionClosed")
  }

  override fun onCloseBleComplete() {
    logger.log(Level.INFO, "onCloseBleComplete")
  }

  override fun onError(error: Throwable) {
    setFailure(error.toString())
    logger.log(Level.INFO, "onError with error: $error")
  }

  override fun onOpCSRGenerationComplete(csr: ByteArray) {
    logger.log(Level.INFO, "onOpCSRGenerationComplete")
    for (i in csr.indices) {
      print(csr[i].toString() + " ")
    }
  }

  override fun onICDRegistrationInfoRequired() {
    logger.log(Level.INFO, "onICDRegistrationInfoRequired")
    currentCommissioner()
      .updateCommissioningICDRegistrationInfo(ICDRegistrationInfo.newBuilder().build())
  }

  override fun onICDRegistrationComplete(errorCode: Long, icdDeviceInfo: ICDDeviceInfo) {
    logger.log(
      Level.INFO,
      "onICDRegistrationComplete with errorCode: $errorCode, symmetricKey: ${icdDeviceInfo.symmetricKey.toHex()}, icdDeviceInfo: $icdDeviceInfo"
    )
  }

  fun getNodeId(): Long {
    return nodeId.get()
  }

  fun getRemoteAddr(): IPAddress {
    return remoteAddr
  }

  fun getRemotePort(): Int {
    return remotePort.get()
  }

  fun getSetupPINCode(): Long {
    return setupPINCode.get()
  }

  fun getDiscriminator(): Int {
    return discriminator.get()
  }

  fun getTimeoutMillis(): Long {
    return timeoutMillis.get()
  }

  fun getOnboardingPayload(): String {
    return onboardingPayload.toString()
  }

  fun getWifiNetworkCredentials(): NetworkCredentials {
    return NetworkCredentials.forWiFi(
      NetworkCredentials.WiFiCredentials(ssid.toString(), password.toString())
    )
  }

  fun getThreadNetworkCredentials(): NetworkCredentials {
    return NetworkCredentials.forThread(
      NetworkCredentials.ThreadCredentials(operationalDataset.toString().hexToByteArray())
    )
  }

  private fun String.hexToByteArray(): ByteArray {
    return chunked(2).map { byteStr -> byteStr.toUByte(16).toByte() }.toByteArray()
  }

  fun getDiscoverOnce(): Boolean {
    return discoverOnce.get()
  }

  fun getUseOnlyOnNetworkDiscovery(): Boolean {
    return useOnlyOnNetworkDiscovery.get()
  }

  private fun ByteArray.toHex(): String =
    joinToString(separator = "") { eachByte -> "%02x".format(eachByte) }

  companion object {
    private val logger = Logger.getLogger(PairingCommand::class.java.name)
  }
}
