// Copyright 2017 Google Inc. 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 java

import (
	"strconv"
	"strings"
	"testing"

	"android/soong/android"
)

func TestKotlin(t *testing.T) {
	ctx, _ := testJava(t, `
		java_library {
			name: "foo",
			srcs: ["a.java", "b.kt"],
		}

		java_library {
			name: "bar",
			srcs: ["b.kt"],
			libs: ["foo"],
			static_libs: ["baz"],
		}

		java_library {
			name: "baz",
			srcs: ["c.java"],
		}
		`)

	fooKotlinc := ctx.ModuleForTests("foo", "android_common").Rule("kotlinc")
	fooJavac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
	fooJar := ctx.ModuleForTests("foo", "android_common").Output("combined/foo.jar")
	fooHeaderJar := ctx.ModuleForTests("foo", "android_common").Output("turbine-combined/foo.jar")

	fooKotlincClasses := fooKotlinc.Output
	fooKotlincHeaderClasses := fooKotlinc.ImplicitOutput

	if len(fooKotlinc.Inputs) != 2 || fooKotlinc.Inputs[0].String() != "a.java" ||
		fooKotlinc.Inputs[1].String() != "b.kt" {
		t.Errorf(`foo kotlinc inputs %v != ["a.java", "b.kt"]`, fooKotlinc.Inputs)
	}

	if len(fooJavac.Inputs) != 1 || fooJavac.Inputs[0].String() != "a.java" {
		t.Errorf(`foo inputs %v != ["a.java"]`, fooJavac.Inputs)
	}

	if !strings.Contains(fooJavac.Args["classpath"], fooKotlincHeaderClasses.String()) {
		t.Errorf("foo classpath %v does not contain %q",
			fooJavac.Args["classpath"], fooKotlincHeaderClasses.String())
	}

	if !inList(fooKotlincClasses.String(), fooJar.Inputs.Strings()) {
		t.Errorf("foo jar inputs %v does not contain %q",
			fooJar.Inputs.Strings(), fooKotlincClasses.String())
	}

	if !inList(fooKotlincHeaderClasses.String(), fooHeaderJar.Inputs.Strings()) {
		t.Errorf("foo header jar inputs %v does not contain %q",
			fooHeaderJar.Inputs.Strings(), fooKotlincHeaderClasses.String())
	}

	bazHeaderJar := ctx.ModuleForTests("baz", "android_common").Output("turbine-combined/baz.jar")
	barKotlinc := ctx.ModuleForTests("bar", "android_common").Rule("kotlinc")

	if len(barKotlinc.Inputs) != 1 || barKotlinc.Inputs[0].String() != "b.kt" {
		t.Errorf(`bar kotlinc inputs %v != ["b.kt"]`, barKotlinc.Inputs)
	}

	if !inList(fooHeaderJar.Output.String(), barKotlinc.Implicits.Strings()) {
		t.Errorf(`expected %q in bar implicits %v`,
			fooHeaderJar.Output.String(), barKotlinc.Implicits.Strings())
	}

	if !inList(bazHeaderJar.Output.String(), barKotlinc.Implicits.Strings()) {
		t.Errorf(`expected %q in bar implicits %v`,
			bazHeaderJar.Output.String(), barKotlinc.Implicits.Strings())
	}
}

func TestKapt(t *testing.T) {
	bp := `
		java_library {
			name: "foo",
			srcs: ["a.java", "b.kt"],
			plugins: ["bar", "baz"],
			errorprone: {
				extra_check_modules: ["my_check"],
			},
		}

		java_plugin {
			name: "bar",
			processor_class: "com.bar",
			srcs: ["b.java"],
		}

		java_plugin {
			name: "baz",
			processor_class: "com.baz",
			srcs: ["b.java"],
		}

		java_plugin {
			name: "my_check",
			srcs: ["b.java"],
		}
	`
	t.Run("", func(t *testing.T) {
		ctx, _ := testJava(t, bp)

		buildOS := ctx.Config().BuildOS.String()

		foo := ctx.ModuleForTests("foo", "android_common")
		kaptStubs := foo.Rule("kapt")
		turbineApt := foo.Description("turbine apt")
		kotlinc := foo.Rule("kotlinc")
		javac := foo.Rule("javac")

		bar := ctx.ModuleForTests("bar", buildOS+"_common").Rule("javac").Output.String()
		baz := ctx.ModuleForTests("baz", buildOS+"_common").Rule("javac").Output.String()

		// Test that the kotlin and java sources are passed to kapt and kotlinc
		if len(kaptStubs.Inputs) != 2 || kaptStubs.Inputs[0].String() != "a.java" || kaptStubs.Inputs[1].String() != "b.kt" {
			t.Errorf(`foo kapt inputs %v != ["a.java", "b.kt"]`, kaptStubs.Inputs)
		}
		if len(kotlinc.Inputs) != 2 || kotlinc.Inputs[0].String() != "a.java" || kotlinc.Inputs[1].String() != "b.kt" {
			t.Errorf(`foo kotlinc inputs %v != ["a.java", "b.kt"]`, kotlinc.Inputs)
		}

		// Test that only the java sources are passed to turbine-apt and javac
		if len(turbineApt.Inputs) != 1 || turbineApt.Inputs[0].String() != "a.java" {
			t.Errorf(`foo turbine apt inputs %v != ["a.java"]`, turbineApt.Inputs)
		}
		if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
			t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
		}

		// Test that the kapt stubs jar is a dependency of turbine-apt
		if !inList(kaptStubs.Output.String(), turbineApt.Implicits.Strings()) {
			t.Errorf("expected %q in turbine-apt implicits %v", kaptStubs.Output.String(), kotlinc.Implicits.Strings())
		}

		turbineAptSrcjarOutput := turbineApt.ImplicitOutputs[0]

		// Test that the turbine-apt srcjar is a dependency of kotlinc and javac rules
		if !inList(turbineAptSrcjarOutput.String(), kotlinc.Implicits.Strings()) {
			t.Errorf("expected %q in kotlinc implicits %v", turbineAptSrcjarOutput.String(), kotlinc.Implicits.Strings())
		}
		if !inList(turbineAptSrcjarOutput.String(), javac.Implicits.Strings()) {
			t.Errorf("expected %q in javac implicits %v", turbineAptSrcjarOutput.String(), javac.Implicits.Strings())
		}

		// Test that the turbine-apt srcjar is extracted by the kotlinc and javac rules
		if kotlinc.Args["srcJars"] != turbineAptSrcjarOutput.String() {
			t.Errorf("expected %q in kotlinc srcjars %v", turbineAptSrcjarOutput.String(), kotlinc.Args["srcJars"])
		}
		if javac.Args["srcJars"] != turbineAptSrcjarOutput.String() {
			t.Errorf("expected %q in javac srcjars %v", turbineAptSrcjarOutput.String(), kotlinc.Args["srcJars"])
		}

		// Test that the turbine-apt header jar is a dependency of the javac rules
		turbineAptHeaderjarOutput := turbineApt.Output
		android.AssertStringListContains(t, "javac dependency", javac.Implicits.Strings(), turbineAptHeaderjarOutput.String())
		android.AssertStringDoesContain(t, "javac classpath", javac.Args["classpath"], turbineAptHeaderjarOutput.String())

		// Test that the kotlinc header jar is a not a dependency of the javac rules
		kotlincHeaderJarOutput := kotlinc.ImplicitOutput
		android.AssertStringListDoesNotContain(t, "javac dependency", javac.Implicits.Strings(), kotlincHeaderJarOutput.String())
		android.AssertStringDoesNotContain(t, "javac classpath", javac.Args["classpath"], kotlincHeaderJarOutput.String())

		// Test that the processors are passed to kapt
		expectedProcessorPath := "-P plugin:org.jetbrains.kotlin.kapt3:apclasspath=" + bar +
			" -P plugin:org.jetbrains.kotlin.kapt3:apclasspath=" + baz
		if kaptStubs.Args["kaptProcessorPath"] != expectedProcessorPath {
			t.Errorf("expected kaptProcessorPath %q, got %q", expectedProcessorPath, kaptStubs.Args["kaptProcessorPath"])
		}
		expectedProcessor := "-P plugin:org.jetbrains.kotlin.kapt3:processors=com.bar -P plugin:org.jetbrains.kotlin.kapt3:processors=com.baz"
		if kaptStubs.Args["kaptProcessor"] != expectedProcessor {
			t.Errorf("expected kaptProcessor %q, got %q", expectedProcessor, kaptStubs.Args["kaptProcessor"])
		}

		// Test that the processors are passed to turbine-apt
		expectedProcessorPath = "--processorpath " + bar + " " + baz
		if !strings.Contains(turbineApt.Args["turbineFlags"], expectedProcessorPath) {
			t.Errorf("expected turbine-apt processorpath %q, got %q", expectedProcessorPath, turbineApt.Args["turbineFlags"])
		}
		expectedProcessor = "--processors com.bar com.baz"
		if !strings.Contains(turbineApt.Args["turbineFlags"], expectedProcessor) {
			t.Errorf("expected turbine-apt processor %q, got %q", expectedProcessor, turbineApt.Args["turbineFlags"])
		}

		// Test that the processors are not passed to javac
		if javac.Args["processorpath"] != "" {
			t.Errorf("expected processorPath '', got %q", javac.Args["processorpath"])
		}
		if javac.Args["processor"] != "-proc:none" {
			t.Errorf("expected processor '-proc:none', got %q", javac.Args["processor"])
		}
	})

	t.Run("errorprone", func(t *testing.T) {
		env := map[string]string{
			"RUN_ERROR_PRONE": "true",
		}

		result := android.GroupFixturePreparers(
			PrepareForTestWithJavaDefaultModules,
			android.FixtureMergeEnv(env),
		).RunTestWithBp(t, bp)

		buildOS := result.Config.BuildOS.String()

		kapt := result.ModuleForTests("foo", "android_common").Rule("kapt")
		javac := result.ModuleForTests("foo", "android_common").Description("javac")
		errorprone := result.ModuleForTests("foo", "android_common").Description("errorprone")

		bar := result.ModuleForTests("bar", buildOS+"_common").Description("javac").Output.String()
		baz := result.ModuleForTests("baz", buildOS+"_common").Description("javac").Output.String()
		myCheck := result.ModuleForTests("my_check", buildOS+"_common").Description("javac").Output.String()

		// Test that the errorprone plugins are not passed to kapt
		expectedProcessorPath := "-P plugin:org.jetbrains.kotlin.kapt3:apclasspath=" + bar +
			" -P plugin:org.jetbrains.kotlin.kapt3:apclasspath=" + baz
		if kapt.Args["kaptProcessorPath"] != expectedProcessorPath {
			t.Errorf("expected kaptProcessorPath %q, got %q", expectedProcessorPath, kapt.Args["kaptProcessorPath"])
		}
		expectedProcessor := "-P plugin:org.jetbrains.kotlin.kapt3:processors=com.bar -P plugin:org.jetbrains.kotlin.kapt3:processors=com.baz"
		if kapt.Args["kaptProcessor"] != expectedProcessor {
			t.Errorf("expected kaptProcessor %q, got %q", expectedProcessor, kapt.Args["kaptProcessor"])
		}

		// Test that the errorprone plugins are not passed to javac
		if javac.Args["processorpath"] != "" {
			t.Errorf("expected processorPath '', got %q", javac.Args["processorpath"])
		}
		if javac.Args["processor"] != "-proc:none" {
			t.Errorf("expected processor '-proc:none', got %q", javac.Args["processor"])
		}

		// Test that the errorprone plugins are passed to errorprone
		expectedProcessorPath = "-processorpath " + myCheck
		if errorprone.Args["processorpath"] != expectedProcessorPath {
			t.Errorf("expected processorpath %q, got %q", expectedProcessorPath, errorprone.Args["processorpath"])
		}
		if errorprone.Args["processor"] != "-proc:none" {
			t.Errorf("expected processor '-proc:none', got %q", errorprone.Args["processor"])
		}
	})
}

func TestKaptEncodeFlags(t *testing.T) {
	// Compares the kaptEncodeFlags against the results of the example implementation at
	// https://kotlinlang.org/docs/reference/kapt.html#apjavac-options-encoding
	tests := []struct {
		in  [][2]string
		out string
	}{
		{
			// empty input
			in:  [][2]string{},
			out: "rO0ABXcEAAAAAA==",
		},
		{
			// common input
			in: [][2]string{
				{"-source", "1.8"},
				{"-target", "1.8"},
			},
			out: "rO0ABXcgAAAAAgAHLXNvdXJjZQADMS44AActdGFyZ2V0AAMxLjg=",
		},
		{
			// input that serializes to a 255 byte block
			in: [][2]string{
				{"-source", "1.8"},
				{"-target", "1.8"},
				{"a", strings.Repeat("b", 218)},
			},
			out: "rO0ABXf/AAAAAwAHLXNvdXJjZQADMS44AActdGFyZ2V0AAMxLjgAAWEA2mJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJi",
		},
		{
			// input that serializes to a 256 byte block
			in: [][2]string{
				{"-source", "1.8"},
				{"-target", "1.8"},
				{"a", strings.Repeat("b", 219)},
			},
			out: "rO0ABXoAAAEAAAAAAwAHLXNvdXJjZQADMS44AActdGFyZ2V0AAMxLjgAAWEA22JiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYg==",
		},
		{
			// input that serializes to a 257 byte block
			in: [][2]string{
				{"-source", "1.8"},
				{"-target", "1.8"},
				{"a", strings.Repeat("b", 220)},
			},
			out: "rO0ABXoAAAEBAAAAAwAHLXNvdXJjZQADMS44AActdGFyZ2V0AAMxLjgAAWEA3GJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmI=",
		},
	}

	for i, test := range tests {
		t.Run(strconv.Itoa(i), func(t *testing.T) {
			got := kaptEncodeFlags(test.in)
			if got != test.out {
				t.Errorf("\nwant %q\n got %q", test.out, got)
			}
		})
	}
}

func TestKotlinCompose(t *testing.T) {
	result := android.GroupFixturePreparers(
		PrepareForTestWithJavaDefaultModules,
	).RunTestWithBp(t, `
		java_library {
			name: "androidx.compose.runtime_runtime",
		}

		java_library_host {
			name: "androidx.compose.compiler_compiler-hosted",
		}

		java_library {
			name: "withcompose",
			srcs: ["a.kt"],
			static_libs: ["androidx.compose.runtime_runtime"],
		}

		java_library {
			name: "nocompose",
			srcs: ["a.kt"],
		}
	`)

	buildOS := result.Config.BuildOS.String()

	composeCompiler := result.ModuleForTests("androidx.compose.compiler_compiler-hosted", buildOS+"_common").Rule("combineJar").Output
	withCompose := result.ModuleForTests("withcompose", "android_common")
	noCompose := result.ModuleForTests("nocompose", "android_common")

	android.AssertStringListContains(t, "missing compose compiler dependency",
		withCompose.Rule("kotlinc").Implicits.Strings(), composeCompiler.String())

	android.AssertStringDoesContain(t, "missing compose compiler plugin",
		withCompose.VariablesForTestsRelativeToTop()["kotlincFlags"], "-Xplugin="+composeCompiler.String())

	android.AssertStringListDoesNotContain(t, "unexpected compose compiler dependency",
		noCompose.Rule("kotlinc").Implicits.Strings(), composeCompiler.String())

	android.AssertStringDoesNotContain(t, "unexpected compose compiler plugin",
		noCompose.VariablesForTestsRelativeToTop()["kotlincFlags"], "-Xplugin="+composeCompiler.String())
}
