/*
 * Copyright 2018 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.
 */
package io.bazel.ruleskotlin.workers.compilers.jvm.utils

import com.google.devtools.build.lib.view.proto.Deps
import java.nio.file.Path
import java.nio.file.Paths
import java.util.*
import java.util.function.Predicate
import java.util.stream.Stream

class JdepsParser private constructor(private val filename: String, private val isImplicit: Predicate<String>) {
    private val packageSuffix: String = " ($filename)"

    private val depMap = HashMap<String, Deps.Dependency.Builder>()
    private val packages = HashSet<String>()

    private var mode = Mode.COLLECT_DEPS

    private fun consumeJarLine(classJarPath: String, kind: Deps.Dependency.Kind) {
        val path = Paths.get(classJarPath)

        // ignore absolute files, -- jdk jar paths etc.
        // only process jar files
        if (!(path.isAbsolute || !classJarPath.endsWith(".jar"))) {
            val entry = depMap.computeIfAbsent(classJarPath) {
                val depBuilder = Deps.Dependency.newBuilder()
                depBuilder.path = classJarPath
                depBuilder.kind = kind

                if (isImplicit.test(classJarPath)) {
                    depBuilder.kind = Deps.Dependency.Kind.IMPLICIT
                }
                depBuilder
            }

            // don't flip an implicit dep.
            if (entry.kind != Deps.Dependency.Kind.IMPLICIT) {
                entry.kind = kind
            }
        }
    }

    private enum class Mode {
        COLLECT_DEPS,
        DETERMINE_JDK,
        COLLECT_PACKAGES_JDK8,
        COLLECT_PACKAGES_JDK9
    }

    // maybe simplify this by tokenizing on whitespace and arrows.
    private fun processLine(line: String) {
        val trimmedLine = line.trim { it <= ' ' }
        when (mode) {
            JdepsParser.Mode.COLLECT_DEPS -> if (!line.startsWith(" ")) {
                val parts = line.split(" -> ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
                if (parts.size == 2) {
                    if (parts[0] != filename) {
                        throw RuntimeException("should only get dependencies for dep: " + filename)
                    }
                    consumeJarLine(parts[1], Deps.Dependency.Kind.EXPLICIT)
                }
            } else {
                mode = Mode.DETERMINE_JDK
                processLine(line)
            }
            JdepsParser.Mode.DETERMINE_JDK -> {
                mode = Mode.COLLECT_PACKAGES_JDK8
                if (!line.endsWith(packageSuffix)) {
                    mode = Mode.COLLECT_PACKAGES_JDK9
                }
                processLine(line)
            }
            JdepsParser.Mode.COLLECT_PACKAGES_JDK8 -> when {
                trimmedLine.endsWith(packageSuffix) -> packages.add(trimmedLine.substring(0, trimmedLine.length - packageSuffix.length))
                trimmedLine.startsWith("-> ") -> {
                    // ignore package detail lines, in the jdk8 format these start with arrows.
                }
                else -> throw RuntimeException("unexpected line while collecting packages: " + line)
            }
            JdepsParser.Mode.COLLECT_PACKAGES_JDK9 -> {
                val pkg = trimmedLine.split("\\s+".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
                packages.add(pkg[0])
            }
        }
    }

    companion object {
        fun pathSuffixMatchingPredicate(directory: Path, vararg jars: String): Predicate<String> {
            val suffixes = jars.map { directory.resolve(it).toString() }
            return Predicate { jar ->
                for (implicitJarsEnding in suffixes) {
                    if (jar.endsWith(implicitJarsEnding)) {
                        return@Predicate true
                    }
                }
                false
            }
        }

        fun parse(label: String, classJar: String, classPath: String, jdepLines: Stream<String>, isImplicit: Predicate<String>): Deps.Dependencies {
            val filename = Paths.get(classJar).fileName.toString()
            val jdepsParser = JdepsParser(filename, isImplicit)
            Stream.of(*classPath.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()).forEach { x -> jdepsParser.consumeJarLine(x, Deps.Dependency.Kind.UNUSED) }
            jdepLines.forEach { jdepsParser.processLine(it) }

            val rootBuilder = Deps.Dependencies.newBuilder()
            rootBuilder.success = false
            rootBuilder.ruleLabel = label

            rootBuilder.addAllContainedPackage(jdepsParser.packages)
            jdepsParser.depMap.values.forEach { b -> rootBuilder.addDependency(b.build()) }

            rootBuilder.success = true
            return rootBuilder.build()
        }
    }
}