/*
 *   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.common

import java.net.InetAddress
import java.net.UnknownHostException
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicInteger
import java.util.concurrent.atomic.AtomicLong

class Argument {
  val name: String
  val type: ArgumentType
  private val minValue: Long
  private val maxValue: Long
  val value: Any
  val desc: String?
  val isOptional: Boolean

  constructor(name: String, value: IPAddress, optional: Boolean) {
    this.name = name
    type = ArgumentType.ADDRESS
    minValue = 0
    maxValue = 0
    this.value = value
    desc = null
    isOptional = optional
  }

  constructor(name: String, value: StringBuffer, desc: String?, optional: Boolean) {
    this.name = name
    type = ArgumentType.STRING
    minValue = 0
    maxValue = 0
    this.value = value
    this.desc = desc
    isOptional = optional
  }

  constructor(name: String, value: AtomicBoolean, desc: String?, optional: Boolean) {
    this.name = name
    type = ArgumentType.BOOL
    minValue = 0
    maxValue = 0
    this.value = value
    this.desc = desc
    isOptional = optional
  }

  constructor(
    name: String,
    min: Short,
    max: Short,
    value: AtomicInteger,
    desc: String?,
    optional: Boolean
  ) {
    this.name = name
    type = ArgumentType.NUMBER_INT16
    minValue = min.toLong()
    maxValue = max.toLong()
    this.value = value
    this.desc = desc
    isOptional = optional
  }

  constructor(
    name: String, min: Int, max: Int, value: AtomicInteger, desc: String?, optional: Boolean
  ) {
    this.name = name
    type = ArgumentType.NUMBER_INT32
    minValue = min.toLong()
    maxValue = max.toLong()
    this.value = value
    this.desc = desc
    isOptional = optional
  }

  constructor(
    name: String, min: Short, max: Short, value: AtomicLong, desc: String?, optional: Boolean
  ) {
    this.name = name
    type = ArgumentType.NUMBER_INT32
    minValue = min.toLong()
    maxValue = max.toLong()
    this.value = value
    this.desc = desc
    isOptional = optional
  }

  constructor(
    name: String, min: Long, max: Long, value: AtomicLong, desc: String?, optional: Boolean
  ) {
    this.name = name
    type = ArgumentType.NUMBER_INT64
    minValue = min
    maxValue = max
    this.value = value
    this.desc = desc
    isOptional = optional
  }

  fun setValue(value: String) {
    var isValidArgument = false
    when (type) {
      ArgumentType.ATTRIBUTE -> {
        val str = this.value as String
        isValidArgument = value == str
      }

      ArgumentType.NUMBER_INT16 -> {
        val numShort = this.value as AtomicInteger
        numShort.set(value.toInt())
        isValidArgument = numShort.toInt() >= minValue && numShort.toInt() <= maxValue
      }

      ArgumentType.NUMBER_INT32 -> {
        val num = this.value as AtomicInteger
        num.set(value.toInt())
        isValidArgument = num.toInt() >= minValue && num.toInt() <= maxValue
      }

      ArgumentType.NUMBER_INT64 -> {
        val numLong = this.value as AtomicLong
        numLong.set(value.toLong())
        isValidArgument = numLong.toInt() >= minValue && numLong.toInt() <= maxValue
      }

      ArgumentType.STRING -> {
        val stringBuffer = this.value as StringBuffer
        stringBuffer.append(value)
        val str = stringBuffer.toString()
        isValidArgument = value == str
      }

      ArgumentType.BOOL -> {
        val atomicBoolean = this.value as AtomicBoolean
        try {
          atomicBoolean.set(value.toBoolean())
          isValidArgument = true
        } catch (e: Exception) {
          isValidArgument = false
        }
      }

      ArgumentType.ADDRESS -> isValidArgument = try {
        val ipAddress = this.value as IPAddress
        ipAddress.setAddress(InetAddress.getByName(value))
        true
      } catch (e: UnknownHostException) {
        false
      }

      else -> {
      }
    }
    require(isValidArgument) { "Invalid argument " + name + ": " + value }
  }
}