/*
 * 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.openwhisk.core.entity

import java.nio.charset.StandardCharsets

import com.typesafe.config.ConfigValue
import pureconfig._
import pureconfig.generic.auto._
import spray.json._
import ByteSize.formatError

object SizeUnits extends Enumeration {

  sealed abstract class Unit() {
    def toBytes(n: Long): Long

    def toKBytes(n: Long): Long

    def toMBytes(n: Long): Long

    def toGBytes(n: Long): Long
  }

  case object BYTE extends Unit {
    def toBytes(n: Long): Long = n

    def toKBytes(n: Long): Long = n / 1024

    def toMBytes(n: Long): Long = n / 1024 / 1024

    def toGBytes(n: Long): Long = n / 1024 / 1024 / 1024
  }

  case object KB extends Unit {
    def toBytes(n: Long): Long = n * 1024

    def toKBytes(n: Long): Long = n

    def toMBytes(n: Long): Long = n / 1024

    def toGBytes(n: Long): Long = n / 1024 / 1024

  }

  case object MB extends Unit {
    def toBytes(n: Long): Long = n * 1024 * 1024

    def toKBytes(n: Long): Long = n * 1024

    def toMBytes(n: Long): Long = n

    def toGBytes(n: Long): Long = n / 1024
  }

  case object GB extends Unit {
    def toBytes(n: Long): Long = n * 1024 * 1024 * 1024

    def toKBytes(n: Long): Long = n * 1024 * 1024

    def toMBytes(n: Long): Long = n * 1024

    def toGBytes(n: Long): Long = n
  }

}

case class ByteSize(size: Long, unit: SizeUnits.Unit) extends Ordered[ByteSize] {

  require(size >= 0, "a negative size of an object is not allowed.")

  def toBytes = unit.toBytes(size)

  def toKB = unit.toKBytes(size)

  def toMB = unit.toMBytes(size)

  def +(other: ByteSize): ByteSize = {
    val commonUnit = SizeUnits.BYTE
    val commonSize = other.toBytes + toBytes
    ByteSize(commonSize, commonUnit)
  }

  def -(other: ByteSize): ByteSize = {
    val commonUnit = SizeUnits.BYTE
    val commonSize = toBytes - other.toBytes
    ByteSize(commonSize, commonUnit)
  }

  def *(other: Int): ByteSize = {
    ByteSize(toBytes * other, SizeUnits.BYTE)
  }

  def /(other: ByteSize): Double = {
    // Without throwing the exception the result would be `Infinity` here
    if (other.toBytes == 0) {
      throw new ArithmeticException
    } else {
      (1.0 * toBytes) / (1.0 * other.toBytes)
    }
  }

  def /(other: Int): ByteSize = {
    ByteSize(toBytes / other, SizeUnits.BYTE)
  }

  def compare(other: ByteSize) = toBytes compare other.toBytes

  override def equals(that: Any): Boolean = that match {
    case t: ByteSize => compareTo(t) == 0
    case _           => false
  }

  override def toString = {
    unit match {
      case SizeUnits.BYTE => s"$size B"
      case SizeUnits.KB   => s"$size KB"
      case SizeUnits.MB   => s"$size MB"
      case SizeUnits.GB   => s"$size GB"
    }
  }
}

object ByteSize {
  private val regex = """(?i)\s?(\d+)\s?(GB|MB|KB|B|G|M|K)\s?""".r.pattern
  protected[entity] val formatError = """Size Unit not supported. Only "B", "K[B]", "M[B]" and "G[B]" are supported."""

  def fromString(sizeString: String): ByteSize = {
    val matcher = regex.matcher(sizeString)
    if (matcher.matches()) {
      val size = matcher.group(1).toLong
      val unit = matcher.group(2).charAt(0).toUpper match {
        case 'B' => SizeUnits.BYTE
        case 'K' => SizeUnits.KB
        case 'M' => SizeUnits.MB
        case 'G' => SizeUnits.GB
      }

      ByteSize(size, unit)
    } else {
      throw new IllegalArgumentException(formatError)
    }
  }
}

object size {

  implicit class SizeInt(n: Int) extends SizeConversion {
    def sizeIn(unit: SizeUnits.Unit): ByteSize = ByteSize(n, unit)
  }

  implicit class SizeLong(n: Long) extends SizeConversion {
    def sizeIn(unit: SizeUnits.Unit): ByteSize = ByteSize(n, unit)
  }

  implicit class SizeString(n: String) extends SizeConversion {
    def sizeIn(unit: SizeUnits.Unit): ByteSize = ByteSize(n.getBytes(StandardCharsets.UTF_8).length, unit)
  }

  implicit class SizeOptionString(n: Option[String]) extends SizeConversion {
    def sizeIn(unit: SizeUnits.Unit): ByteSize =
      n map { s =>
        s.sizeIn(unit)
      } getOrElse {
        ByteSize(0, unit)
      }
  }

  // Creation of an intermediary Config object is necessary here, since "getBytes" is only part of that interface.
  implicit val pureconfigReader =
    ConfigReader[ConfigValue].map(v => ByteSize(v.atKey("key").getBytes("key"), SizeUnits.BYTE))

  protected[core] implicit val serdes = new RootJsonFormat[ByteSize] {
    def write(b: ByteSize) = JsString(b.toString)

    def read(value: JsValue): ByteSize = value match {
      case JsString(s) => ByteSize.fromString(s)
      case _           => deserializationError(formatError)
    }
  }
}

trait SizeConversion {
  def B = sizeIn(SizeUnits.BYTE)

  def KB = sizeIn(SizeUnits.KB)

  def MB = sizeIn(SizeUnits.MB)

  def GB: ByteSize = sizeIn(SizeUnits.GB)

  def bytes = B

  def kilobytes = KB

  def megabytes = MB

  def gigabytes: ByteSize = GB

  def sizeInBytes = sizeIn(SizeUnits.BYTE)

  def sizeIn(unit: SizeUnits.Unit): ByteSize
}
