// Copyright 2014 The Bazel 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.

// Copied from bazel core and there is some code in other branches which will use the some of the unused elements. Fix
// this later on.
@file:Suppress("unused","MemberVisibilityCanBePrivate")
package io.bazel.kotlin.builder.utils.jars

import java.io.FileNotFoundException
import java.io.IOException
import java.nio.file.Files
import java.nio.file.Path
import java.time.LocalDateTime
import java.time.ZoneId
import java.util.*
import java.util.jar.Attributes
import java.util.jar.JarEntry
import java.util.jar.JarFile
import java.util.jar.JarOutputStream
import java.util.zip.CRC32

/**
 * A simple helper class for creating Jar files. All Jar entries are sorted alphabetically. Allows
 * normalization of Jar entries by setting the timestamp of non-.class files to the DOS epoch.
 * Timestamps of .class files are set to the DOS epoch + 2 seconds (The zip timestamp granularity)
 * Adjusting the timestamp for .class files is necessary since otherwise javac will recompile java
 * files if both the java file and its .class file are present.
 */
open class JarHelper internal constructor (
    // The path to the Jar we want to create
    protected val jarPath: Path,
    // The properties to describe how to create the Jar
    protected val normalize: Boolean = true,
    protected val verbose: Boolean = false,
    compression: Boolean = true
) {
    private var storageMethod: Int = JarEntry.DEFLATED
    // The state needed to create the Jar
    private val names: MutableSet<String> = HashSet()

    init {
        setCompression(compression)
    }

    /**
     * Enables or disables compression for the Jar file entries.
     *
     * @param compression if true enables compressions for the Jar file entries.
     */
    private fun setCompression(compression: Boolean) {
        storageMethod = if (compression) JarEntry.DEFLATED else JarEntry.STORED
    }

    /**
     * Returns the normalized timestamp for a jar entry based on its name. This is necessary since
     * javac will, when loading a class X, prefer a source file to a class file, if both files have
     * the same timestamp. Therefore, we need to adjust the timestamp for class files to slightly
     * after the normalized time.
     *
     * @param name The name of the file for which we should return the normalized timestamp.
     * @return the time for a new Jar file entry in milliseconds since the epoch.
     */
    private fun normalizedTimestamp(name: String): Long {
        return if (name.endsWith(".class")) {
            DEFAULT_TIMESTAMP + MINIMUM_TIMESTAMP_INCREMENT
        } else {
            DEFAULT_TIMESTAMP
        }
    }

    /**
     * Returns the time for a new Jar file entry in milliseconds since the epoch. Uses JarCreator.DEFAULT_TIMESTAMP]
     * for normalized entries, [System.currentTimeMillis] otherwise.
     *
     * @param filename The name of the file for which we are entering the time
     * @return the time for a new Jar file entry in milliseconds since the epoch.
     */
    private fun newEntryTimeMillis(filename: String): Long {
        return if (normalize) normalizedTimestamp(filename) else System.currentTimeMillis()
    }

    /**
     * Writes an entry with specific contents to the jar. Directory entries must include the trailing
     * '/'.
     */
    @Throws(IOException::class)
    private fun writeEntry(out: JarOutputStream, name: String, content: ByteArray) {
        if (names.add(name)) {
            // Create a new entry
            val entry = JarEntry(name)
            entry.time = newEntryTimeMillis(name)
            val size = content.size
            entry.size = size.toLong()
            if (size == 0) {
                entry.method = JarEntry.STORED
                entry.crc = 0
                out.putNextEntry(entry)
            } else {
                entry.method = storageMethod
                if (storageMethod == JarEntry.STORED) {
                    val crc = CRC32()
                    crc.update(content)
                    entry.crc = crc.value
                }
                out.putNextEntry(entry)
                out.write(content)
            }
            out.closeEntry()
        }
    }

    /**
     * Writes a standard Java manifest entry into the JarOutputStream. This includes the directory
     * entry for the "META-INF" directory
     *
     * @param content the Manifest content to write to the manifest entry.
     * @throws IOException
     */
    @Throws(IOException::class)
    protected fun writeManifestEntry(out: JarOutputStream, content: ByteArray) {
        val oldStorageMethod = storageMethod
        // Do not compress small manifest files, the compressed one is frequently
        // larger than the original. The threshold of 256 bytes is somewhat arbitrary.
        if (content.size < 256) {
            storageMethod = JarEntry.STORED
        }
        try {
            writeEntry(out, MANIFEST_DIR, byteArrayOf())
            writeEntry(out, MANIFEST_NAME, content)
        } finally {
            storageMethod = oldStorageMethod
        }
    }

    /**
     * Copies file or directory entries from the file system into the jar. Directory entries will be
     * detected and their names automatically '/' suffixed.
     */
    @Throws(IOException::class)
    protected fun JarOutputStream.copyEntry(name: String, path: Path) {
        var normalizedName = name
        if (!names.contains(normalizedName)) {
            if (!Files.exists(path)) {
                throw FileNotFoundException("${path.toAbsolutePath()} (No such file or directory)")
            }
            val isDirectory = Files.isDirectory(path)
            if (isDirectory && !normalizedName.endsWith("/")) {
                normalizedName = "$normalizedName/" // always normalize directory names before checking set
            }
            if (names.add(normalizedName)) {
                if (verbose) {
                    System.err.println("adding $path")
                }
                // Create a new entry
                val size = if (isDirectory) 0 else Files.size(path)
                val outEntry = JarEntry(normalizedName)
                val newtime = if (normalize) normalizedTimestamp(normalizedName) else Files.getLastModifiedTime(path).toMillis()
                outEntry.time = newtime
                outEntry.size = size
                if (size == 0L) {
                    outEntry.method = JarEntry.STORED
                    outEntry.crc = 0
                    putNextEntry(outEntry)
                } else {
                    outEntry.method = storageMethod
                    if (storageMethod == JarEntry.STORED) {
                        // ZipFile requires us to calculate the CRC-32 for any STORED entry.
                        // It would be nicer to do this via DigestInputStream, but
                        // the architecture of ZipOutputStream requires us to know the CRC-32
                        // before we write the data to the stream.
                        val bytes = Files.readAllBytes(path)
                        val crc = CRC32()
                        crc.update(bytes)
                        outEntry.crc = crc.value
                        putNextEntry(outEntry)
                        write(bytes)
                    } else {
                        putNextEntry(outEntry)
                        Files.copy(path, this)
                    }
                }
                closeEntry()
            }
        }
    }

    /**
     * Copies a a single entry into the jar. This variant differs from the other [copyEntry] in two ways. Firstly the
     * jar contents are already loaded in memory and Secondly the [name] and [path] entries don't necessarily have a
     * correspondence.
     *
     * @param path the path used to retrieve the timestamp in case normalize is disabled.
     * @param data if this is empty array then the entry is a directory.
     */
    protected fun JarOutputStream.copyEntry(name: String, path: Path? = null, data: ByteArray = EMPTY_BYTEARRAY) {
        val outEntry = JarEntry(name)
        outEntry.time = when {
            normalize -> normalizedTimestamp(name)
            else -> Files.getLastModifiedTime(checkNotNull(path)).toMillis()
        }
        outEntry.size = data.size.toLong()

        if (data.isEmpty()) {
            outEntry.method = JarEntry.STORED
            outEntry.crc = 0
            putNextEntry(outEntry)
        } else {
            outEntry.method = storageMethod
            if (storageMethod == JarEntry.STORED) {
                val crc = CRC32()
                crc.update(data)
                outEntry.crc = crc.value
                putNextEntry(outEntry)
                write(data)
            } else {
                putNextEntry(outEntry)
                write(data)
            }
        }
        closeEntry()
    }

    companion object {
        const val MANIFEST_DIR = "META-INF/"
        const val MANIFEST_NAME = JarFile.MANIFEST_NAME
        const val SERVICES_DIR = "META-INF/services/"
        internal val EMPTY_BYTEARRAY = ByteArray(0)
        /** Normalize timestamps.  */
        val DEFAULT_TIMESTAMP = LocalDateTime.of(1980, 1, 1, 0, 0, 0)
            .atZone(ZoneId.systemDefault())
            .toInstant()
            .toEpochMilli()

        // These attributes are used by JavaBuilder, Turbine, and ijar.
        // They must all be kept in sync.
        val TARGET_LABEL = Attributes.Name("Target-Label")
        val INJECTING_RULE_KIND = Attributes.Name("Injecting-Rule-Kind")

        // ZIP timestamps have a resolution of 2 seconds.
        // see http://www.info-zip.org/FAQ.html#limits
        const val MINIMUM_TIMESTAMP_INCREMENT = 2000L
    }
}
