/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.daffodil.dpath

import java.lang.{ Boolean => JBoolean }
import java.lang.{ Byte => JByte }
import java.lang.{ Double => JDouble }
import java.lang.{ Float => JFloat }
import java.lang.{ Integer => JInt }
import java.lang.{ Long => JLong }
import java.lang.{ Short => JShort }
import java.math.{ BigDecimal => JBigDecimal }
import java.math.{ BigInteger => JBigInt }

import org.apache.daffodil.calendar.DFDLDate
import org.apache.daffodil.calendar.DFDLDateTime
import org.apache.daffodil.dpath.NodeInfo.PrimType
import org.apache.daffodil.infoset.DataValue.DataValueBigDecimal
import org.apache.daffodil.infoset.DataValue.DataValueBigInt
import org.apache.daffodil.infoset.DataValue.DataValueBool
import org.apache.daffodil.infoset.DataValue.DataValueByte
import org.apache.daffodil.infoset.DataValue.DataValueDate
import org.apache.daffodil.infoset.DataValue.DataValueDateTime
import org.apache.daffodil.infoset.DataValue.DataValueDouble
import org.apache.daffodil.infoset.DataValue.DataValueFloat
import org.apache.daffodil.infoset.DataValue.DataValueInt
import org.apache.daffodil.infoset.DataValue.DataValueLong
import org.apache.daffodil.infoset.DataValue.DataValuePrimitive
import org.apache.daffodil.infoset.DataValue.DataValueShort
import org.apache.daffodil.infoset.DataValue.DataValueString
import org.apache.daffodil.infoset.DataValue.DataValueTime
import org.apache.daffodil.util.Numbers.asBigInt
import org.apache.daffodil.util.Numbers.asBoolean
import org.apache.daffodil.util.Numbers.asDouble

case object BooleanToLong extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueLong =
    JLong.valueOf(if (asBoolean(a.getAnyRef) == true) 1L else 0L)
}

case object BooleanToString extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueString =
    if (asBoolean(a.getAnyRef) == true) "true" else "false"
}

case object DateTimeToDate extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueDate = {
    a.getAnyRef match {
      case dt: DFDLDateTime => dt.toDate
      case _ => throw new NumberFormatException("xs:dateTime expected but an invalid type was received.")
    }
  }
}
case object DateTimeToTime extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueTime = {
    a.getAnyRef match {
      case dt: DFDLDateTime => dt.toTime
      case _ => throw new NumberFormatException("xs:dateTime expected but an invalid type was received.")
    }
  }
}
case object DateToDateTime extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueDateTime = {
    a.getAnyRef match {
      case d: DFDLDate => d.toDateTime
      case _ => throw new NumberFormatException("xs:date expected but an invalid type was received.")
    }
  }
}
case object DecimalToInteger extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigInt =
    PrimType.Integer.fromNumber(a.getBigDecimal).getBigInt
}
case object DecimalToLong extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueLong =
    PrimType.Long.fromNumber(a.getBigDecimal).getLong
}
case object DecimalToDouble extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueDouble =
    PrimType.Double.fromNumber(a.getBigDecimal).getDouble
}
case object DecimalToNonNegativeInteger extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigInt =
    PrimType.NonNegativeInteger.fromNumber(a.getBigDecimal).getBigInt
}
case object DecimalToUnsignedLong extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigInt =
    PrimType.UnsignedLong.fromNumber(a.getBigDecimal).getBigInt
}
case object DecimalToBoolean extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBool = {
    val d = a.getBigDecimal
    val comp = d.compareTo(JBigDecimal.ZERO)
    val b =
      if (comp == 0) false
      else true
    asBoolean(b)
  }
}
case object DoubleToDecimal extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigDecimal =
    PrimType.Decimal.fromNumber(a.getDouble).getBigDecimal
}
case object DoubleToFloat extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueFloat =
    PrimType.Float.fromNumber(a.getDouble).getFloat
}
case object DoubleToLong extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueLong =
    PrimType.Long.fromNumber(a.getDouble).getLong
}
case object DoubleToUnsignedLong extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigInt =
    asBigInt(PrimType.UnsignedLong.fromNumber(a.getDouble).getAnyRef)
}
case object DoubleToBoolean extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBool = {
    val d = a.getDouble
    val b =
      if (d == 0.0) false
      else if (d.isNaN()) false
      else true
    asBoolean(b)
  }
}
case object FloatToDouble extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueDouble =
    PrimType.Double.fromNumber(a.getFloat).getDouble
}
case object IntegerToDecimal extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigDecimal =
    PrimType.Decimal.fromNumber(a.getBigInt).getBigDecimal
}
case object IntegerToUnsignedLong extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigInt =
    PrimType.UnsignedLong.fromNumber(a.getBigInt).getBigInt
}
case object LongToBoolean extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBool =
    asBoolean(if (a.getLong == 0) false else true)
}
case object LongToByte extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueByte =
    PrimType.Byte.fromNumber(a.getLong).getByte
}
case object LongToDecimal extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigDecimal =
    PrimType.Decimal.fromNumber(a.getLong).getBigDecimal
}
case object LongToDouble extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueDouble =
    PrimType.Double.fromNumber(a.getLong).getDouble
}
case object LongToFloat extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueFloat =
    PrimType.Float.fromNumber(a.getLong).getFloat
}
case object LongToInt extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueInt =
    PrimType.Int.fromNumber(a.getLong).getInt
}

case object LongToInteger extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigInt =
    PrimType.Integer.fromNumber(a.getLong).getBigInt
}

case object LongToShort extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueShort =
    PrimType.Short.fromNumber(a.getLong).getShort
}

case object LongToArrayIndex extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueLong =
    PrimType.Long.fromNumber(a.getLong).getLong
}
case object LongToUnsignedByte extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueShort =
    PrimType.UnsignedByte.fromNumber(a.getLong).getShort
}
case object LongToUnsignedInt extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueLong =
    PrimType.UnsignedInt.fromNumber(a.getLong).getLong
}
case object LongToUnsignedShort extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueInt =
    PrimType.UnsignedShort.fromNumber(a.getLong).getInt
}

case object LongToNonNegativeInteger extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigInt =
    PrimType.NonNegativeInteger.fromNumber(a.getLong).getBigInt
}

case object LongToUnsignedLong extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigInt =
    PrimType.UnsignedLong.fromNumber(a.getLong).getBigInt
}

case object NumericToDouble extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueDouble =
    asDouble(a.getAnyRef)
}

case object StringToBoolean extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBool =
    PrimType.Boolean.fromXMLString(a.getString).getBoolean
}
case object StringToDecimal extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigDecimal =
    PrimType.Decimal.fromXMLString(a.getString).getBigDecimal
}
case object StringToDouble extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueDouble =
    PrimType.Double.fromXMLString(a.getString).getDouble
}
case object StringToLong extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueLong =
    PrimType.Long.fromXMLString(a.getString).getLong
}
case object StringToUnsignedLong extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigInt =
    PrimType.UnsignedLong.fromXMLString(a.getString).getBigInt
}

/**
 * Summary: Computes the effective boolean value of the sequence \$arg.
 *
 * If \$arg is the empty sequence, fn:boolean returns false.
 *
 * If \$arg is a sequence whose first item is a node, fn:boolean returns true.
 *
 * If \$arg is a singleton value of type xs:boolean or a derived from
 * xs:boolean, fn:boolean returns \$arg.
 *
 * If \$arg is a singleton value of type xs:string or a type derived from
 * xs:string, xs:anyURI or a type derived from xs:anyURI or xs:untypedAtomic,
 * fn:boolean returns false if the operand value has zero length; otherwise
 * it returns true.
 *
 * If \$arg is a singleton value of any numeric type or a type derived
 * from a numeric type, fn:boolean returns false if the operand value
 * is NaN or is numerically equal to zero; otherwise it returns true.
 *
 * In all other cases, fn:boolean raises a type error [err:FORG0006].
 */
case object FNToBoolean extends Converter {
  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBool = {
    val res = a.getAnyRef match {
      case b: JBoolean => b.booleanValue()
      case s: String => if (s.length == 0) false else true
      case d: JDouble => if (d.isNaN() || d == 0) false else true
      case f: JFloat => if (f.isNaN() || f == 0) false else true
      //
      // BigDecimal does not have a representation for NaN or Infinite
      case bd: JBigDecimal => if (bd.compareTo(JBigDecimal.ZERO) == 0) false else true
      case b: JByte => if (b == 0) false else true
      case s: JShort => if (s == 0) false else true
      case i: JInt => if (i == 0) false else true
      case l: JLong => if (l == 0) false else true
      case bi: JBigInt => if (bi.compareTo(JBigInt.ZERO) == 0) false else true
      // TODO: Once sequences are supported, fill in these case statements
      //case s: LocalSequence if s.length == 0 => false
      //case s: LocalSequence if s(0) == Node => true
      case _ => throw new NumberFormatException("Invalid argument type.")
    }
    res
  }
}
