/*
 * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
 * that can be found in the license/LICENSE.txt file.
 */

package org.jetbrains.kotlin.generators.builtins.ranges

import org.jetbrains.kotlin.generators.builtins.PrimitiveType
import org.jetbrains.kotlin.generators.builtins.generateBuiltIns.BuiltInsSourceGenerator
import java.io.PrintWriter

class GeneratePrimitives(out: PrintWriter) : BuiltInsSourceGenerator(out) {
    companion object {
        internal val binaryOperators: Map<String, String> = mapOf(
            "plus" to "Adds the other value to this value.",
            "minus" to "Subtracts the other value from this value.",
            "times" to "Multiplies this value by the other value.",
            "div" to "Divides this value by the other value.",
            "mod" to "Calculates the remainder of dividing this value by the other value.",
            "rem" to "Calculates the remainder of dividing this value by the other value."
        )
        internal val unaryOperators: Map<String, String> = mapOf(
            "inc" to "Increments this value.",
            "dec" to "Decrements this value.",
            "unaryPlus" to "Returns this value.",
            "unaryMinus" to "Returns the negative of this value.")
        internal val shiftOperators: Map<String, String> = mapOf(
            "shl" to "Shifts this value left by the [bitCount] number of bits.",
            "shr" to "Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with copies of the sign bit.",
            "ushr" to "Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with zeros.")
        internal val bitwiseOperators: Map<String, String> = mapOf(
            "and" to "Performs a bitwise AND operation between the two values.",
            "or" to "Performs a bitwise OR operation between the two values.",
            "xor" to "Performs a bitwise XOR operation between the two values.")
    }
    private val typeDescriptions: Map<PrimitiveType, String> = mapOf(
            PrimitiveType.DOUBLE to "double-precision 64-bit IEEE 754 floating point number",
            PrimitiveType.FLOAT to "single-precision 32-bit IEEE 754 floating point number",
            PrimitiveType.LONG to "64-bit signed integer",
            PrimitiveType.INT to "32-bit signed integer",
            PrimitiveType.SHORT to "16-bit signed integer",
            PrimitiveType.BYTE to "8-bit signed integer",
            PrimitiveType.CHAR to "16-bit Unicode character"
    )

    private fun primitiveConstants(type: PrimitiveType): List<Any> = when (type) {
        PrimitiveType.INT -> listOf(java.lang.Integer.MIN_VALUE, java.lang.Integer.MAX_VALUE)
        PrimitiveType.BYTE -> listOf(java.lang.Byte.MIN_VALUE, java.lang.Byte.MAX_VALUE)
        PrimitiveType.SHORT -> listOf(java.lang.Short.MIN_VALUE, java.lang.Short.MAX_VALUE)
        PrimitiveType.LONG -> listOf((java.lang.Long.MIN_VALUE + 1).toString() + "L - 1L", java.lang.Long.MAX_VALUE.toString() + "L")
//        PrimitiveType.DOUBLE -> listOf(java.lang.Double.MIN_VALUE, java.lang.Double.MAX_VALUE, "1.0/0.0", "-1.0/0.0", "0.0/0.0")
//        PrimitiveType.FLOAT -> listOf(java.lang.Float.MIN_VALUE, java.lang.Float.MAX_VALUE, "1.0F/0.0F", "-1.0F/0.0F", "0.0F/0.0F").map { it as? String ?: "${it}F" }
        else -> throw IllegalArgumentException("type: $type")
    }

    override fun generateBody() {
        for (kind in PrimitiveType.onlyNumeric) {
            val className = kind.capitalized
            generateDoc(kind)
            out.println("public class $className private constructor() : Number(), Comparable<$className> {")

            out.print("    companion object {")
            if (kind == PrimitiveType.FLOAT || kind == PrimitiveType.DOUBLE) {
                //val (minValue, maxValue, posInf, negInf, nan) = primitiveConstants(kind)
                out.println("""
        /**
         * A constant holding the smallest *positive* nonzero value of $className.
         */
        public val MIN_VALUE: $className

        /**
         * A constant holding the largest positive finite value of $className.
         */
        public val MAX_VALUE: $className

        /**
         * A constant holding the positive infinity value of $className.
         */
        public val POSITIVE_INFINITY: $className

        /**
         * A constant holding the negative infinity value of $className.
         */
        public val NEGATIVE_INFINITY: $className

        /**
         * A constant holding the "not a number" value of $className.
         */
        public val NaN: $className""")
            }
            if (kind == PrimitiveType.INT || kind == PrimitiveType.LONG || kind == PrimitiveType.SHORT || kind == PrimitiveType.BYTE) {
                val (minValue, maxValue) = primitiveConstants(kind)
                out.println("""
        /**
         * A constant holding the minimum value an instance of $className can have.
         */
        public const val MIN_VALUE: $className = $minValue

        /**
         * A constant holding the maximum value an instance of $className can have.
         */
        public const val MAX_VALUE: $className = $maxValue""")
            }
            if (kind.byteSize != null) {
                out.println("""
        /**
         * The number of bytes used to represent an instance of $className in a binary form.
         */
        @SinceKotlin("1.3")
        public const val SIZE_BYTES: Int = ${kind.byteSize}

        /**
         * The number of bits used to represent an instance of $className in a binary form.
         */
        @SinceKotlin("1.3")
        public const val SIZE_BITS: Int = ${kind.byteSize * 8}""")
            }
            out.println("""    }""")

            generateCompareTo(kind)

            generateBinaryOperators(kind)
            generateUnaryOperators(kind)
            generateRangeTo(kind)

            if (kind == PrimitiveType.INT || kind == PrimitiveType.LONG) {
                generateBitShiftOperators(className)
            }
            if (kind == PrimitiveType.INT || kind == PrimitiveType.LONG /* || kind == PrimitiveType.BYTE || kind == PrimitiveType.SHORT */) {
                generateBitwiseOperators(className, since = if (kind == PrimitiveType.BYTE || kind == PrimitiveType.SHORT) "1.1" else null)
            }

            generateConversions()

            out.println("}\n")
        }
    }

    private fun generateDoc(kind: PrimitiveType) {
        out.println("/**")
        out.println(" * Represents a ${typeDescriptions[kind]}.")
        out.println(" * On the JVM, non-nullable values of this type are represented as values of the primitive type `${kind.name.toLowerCase()}`.")
        out.println(" */")
    }

    private fun generateCompareTo(thisKind: PrimitiveType) {
        for (otherKind in PrimitiveType.onlyNumeric) {
            out.println("""
    /**
     * Compares this value with the specified value for order.
     * Returns zero if this value is equal to the specified other value, a negative number if it's less than other,
     * or a positive number if it's greater than other.
     */""")
            out.print("    public ")
            if (otherKind == thisKind) out.print("override ")
            out.println("operator fun compareTo(other: ${otherKind.capitalized}): Int")
        }
        out.println()
    }

    private fun generateBinaryOperators(thisKind: PrimitiveType) {
        for ((name, doc) in binaryOperators) {
            generateOperator(name, doc, thisKind)
        }
    }

    private fun generateOperator(name: String, doc: String, thisKind: PrimitiveType) {
        for (otherKind in PrimitiveType.onlyNumeric) {
            val returnType = getOperatorReturnType(thisKind, otherKind)

            out.println("    /** $doc */")
            when (name) {
                "rem" ->
                    out.println("    @SinceKotlin(\"1.1\")")

                "mod" ->
                    out.println("    @Deprecated(\"Use rem(other) instead\", ReplaceWith(\"rem(other)\"), DeprecationLevel.ERROR)")
            }
            out.println("    public operator fun $name(other: ${otherKind.capitalized}): ${returnType.capitalized}")
        }
        out.println()
    }

    private fun generateRangeTo(thisKind: PrimitiveType) {
        for (otherKind in PrimitiveType.onlyNumeric) {
            val returnType =
                maxByDomainCapacity(thisKind, otherKind)
                .let { if (it == PrimitiveType.CHAR) it else maxByDomainCapacity(it, PrimitiveType.INT) }
            if (returnType == PrimitiveType.DOUBLE || returnType == PrimitiveType.FLOAT)
                continue
            out.println("     /** Creates a range from this value to the specified [other] value. */")
            out.println("    public operator fun rangeTo(other: ${otherKind.capitalized}): ${returnType.capitalized}Range")
        }
        out.println()

    }

    private fun generateUnaryOperators(kind: PrimitiveType) {
        for ((name, doc) in unaryOperators) {
            val returnType = if (kind in listOf(PrimitiveType.SHORT, PrimitiveType.BYTE, PrimitiveType.CHAR) &&
                                 name in listOf("unaryPlus", "unaryMinus")) "Int" else kind.capitalized
            out.println("    /** $doc */")
            out.println("    public operator fun $name(): $returnType")
        }
        out.println()
    }

    private fun generateBitShiftOperators(className: String) {
        for ((name, doc) in shiftOperators) {
            out.println("    /** $doc */")
            out.println("    public infix fun $name(bitCount: Int): $className")
        }
    }
    private fun generateBitwiseOperators(className: String, since: String?) {
        for ((name, doc) in bitwiseOperators) {
            out.println("    /** $doc */")
            since?.let { out.println("    @SinceKotlin(\"$it\")") }
            out.println("    public infix fun $name(other: $className): $className")
        }
        out.println("    /** Inverts the bits in this value. */")
        since?.let { out.println("    @SinceKotlin(\"$it\")") }
        out.println("    public fun inv(): $className")
        out.println()
    }

    private fun generateConversions() {
        for (otherKind in PrimitiveType.exceptBoolean) {
            val name = otherKind.capitalized
            out.println("    public override fun to$name(): $name")
        }
    }

    private fun maxByDomainCapacity(type1: PrimitiveType, type2: PrimitiveType): PrimitiveType
            = if (type1.ordinal > type2.ordinal) type1 else type2

    private fun getOperatorReturnType(kind1: PrimitiveType, kind2: PrimitiveType): PrimitiveType {
        require(kind1 != PrimitiveType.BOOLEAN) { "kind1 must not be BOOLEAN" }
        require(kind2 != PrimitiveType.BOOLEAN) { "kind2 must not be BOOLEAN" }
        return maxByDomainCapacity(maxByDomainCapacity(kind1, kind2), PrimitiveType.INT)
    }
}
