// Copyright (C) 2021 The Android Open Source Project
//
// 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 apex

import (
	"reflect"
	"testing"

	"android/soong/android"
	"android/soong/java"
	"github.com/google/blueprint"
)

// Contains tests for java.CreateClasspathElements logic from java/classpath_element.go that
// requires apexes.

// testClasspathElementContext is a ClasspathElementContext suitable for use in tests.
type testClasspathElementContext struct {
	testContext *android.TestContext
	module      android.Module
	errs        []error
}

func (t *testClasspathElementContext) OtherModuleHasProvider(module blueprint.Module, provider blueprint.ProviderKey) bool {
	return t.testContext.ModuleHasProvider(module, provider)
}

func (t *testClasspathElementContext) OtherModuleProvider(module blueprint.Module, provider blueprint.ProviderKey) interface{} {
	return t.testContext.ModuleProvider(module, provider)
}

func (t *testClasspathElementContext) ModuleErrorf(fmt string, args ...interface{}) {
	t.errs = append(t.errs, t.testContext.ModuleErrorf(t.module, fmt, args...))
}

var _ java.ClasspathElementContext = (*testClasspathElementContext)(nil)

func TestCreateClasspathElements(t *testing.T) {
	preparer := android.GroupFixturePreparers(
		prepareForTestWithPlatformBootclasspath,
		prepareForTestWithArtApex,
		prepareForTestWithMyapex,
		// For otherapex.
		android.FixtureMergeMockFs(android.MockFS{
			"system/sepolicy/apex/otherapex-file_contexts": nil,
		}),
		java.PrepareForTestWithJavaSdkLibraryFiles,
		java.FixtureWithLastReleaseApis("foo", "othersdklibrary"),
		android.FixtureWithRootAndroidBp(`
		apex {
			name: "com.android.art",
			key: "com.android.art.key",
 			bootclasspath_fragments: [
				"art-bootclasspath-fragment",
			],
			java_libs: [
				"othersdklibrary",
			],
			updatable: false,
		}

		apex_key {
			name: "com.android.art.key",
			public_key: "com.android.art.avbpubkey",
			private_key: "com.android.art.pem",
		}

		bootclasspath_fragment {
			name: "art-bootclasspath-fragment",
			apex_available: [
				"com.android.art",
			],
			contents: [
				"baz",
				"quuz",
			],
		}

		java_library {
			name: "baz",
			apex_available: [
				"com.android.art",
			],
			srcs: ["b.java"],
			installable: true,
		}

		java_library {
			name: "quuz",
			apex_available: [
				"com.android.art",
			],
			srcs: ["b.java"],
			installable: true,
		}

		apex {
			name: "myapex",
			key: "myapex.key",
 			bootclasspath_fragments: [
				"mybootclasspath-fragment",
			],
			java_libs: [
				"othersdklibrary",
			],
			updatable: false,
		}

		apex_key {
			name: "myapex.key",
			public_key: "testkey.avbpubkey",
			private_key: "testkey.pem",
		}

		bootclasspath_fragment {
			name: "mybootclasspath-fragment",
			apex_available: [
				"myapex",
			],
			contents: [
				"bar",
			],
		}

		java_library {
			name: "bar",
			srcs: ["b.java"],
			installable: true,
			apex_available: ["myapex"],
			permitted_packages: ["bar"],
		}

		java_sdk_library {
			name: "foo",
			srcs: ["b.java"],
		}

		java_sdk_library {
			name: "othersdklibrary",
			srcs: ["b.java"],
			shared_library: false,
			apex_available: [
				"com.android.art",
				"myapex",
			],
		}

		bootclasspath_fragment {
			name: "non-apex-fragment",
			contents: ["othersdklibrary"],
		}

		apex {
			name: "otherapex",
			key: "otherapex.key",
			java_libs: [
				"otherapexlibrary",
			],
			updatable: false,
		}

		apex_key {
			name: "otherapex.key",
			public_key: "testkey.avbpubkey",
			private_key: "testkey.pem",
		}

		java_library {
			name: "otherapexlibrary",
			srcs: ["b.java"],
			installable: true,
			apex_available: ["otherapex"],
			permitted_packages: ["otherapexlibrary"],
		}

		platform_bootclasspath {
			name: "myplatform-bootclasspath",

			fragments: [
				{
					apex: "com.android.art",
					module: "art-bootclasspath-fragment",
				},
			],
		}
	`),
	)

	result := preparer.RunTest(t)

	artFragment := result.Module("art-bootclasspath-fragment", "android_common_apex10000")
	artBaz := result.Module("baz", "android_common_apex10000")
	artQuuz := result.Module("quuz", "android_common_apex10000")

	myFragment := result.Module("mybootclasspath-fragment", "android_common_apex10000")
	myBar := result.Module("bar", "android_common_apex10000")

	nonApexFragment := result.Module("non-apex-fragment", "android_common")
	other := result.Module("othersdklibrary", "android_common_apex10000")

	otherApexLibrary := result.Module("otherapexlibrary", "android_common_apex10000")

	platformFoo := result.Module("quuz", "android_common")

	bootclasspath := result.Module("myplatform-bootclasspath", "android_common")

	// Use a custom assertion method instead of AssertDeepEquals as the latter formats the output
	// using %#v which results in meaningless output as ClasspathElements are pointers.
	assertElementsEquals := func(t *testing.T, message string, expected, actual java.ClasspathElements) {
		if !reflect.DeepEqual(expected, actual) {
			t.Errorf("%s: expected:\n  %s\n got:\n  %s", message, expected, actual)
		}
	}

	expectFragmentElement := func(module android.Module, contents ...android.Module) java.ClasspathElement {
		return &java.ClasspathFragmentElement{module, contents}
	}
	expectLibraryElement := func(module android.Module) java.ClasspathElement {
		return &java.ClasspathLibraryElement{module}
	}

	newCtx := func() *testClasspathElementContext {
		return &testClasspathElementContext{testContext: result.TestContext, module: bootclasspath}
	}

	// Verify that CreateClasspathElements works when given valid input.
	t.Run("art:baz, art:quuz, my:bar, foo", func(t *testing.T) {
		ctx := newCtx()
		elements := java.CreateClasspathElements(ctx, []android.Module{artBaz, artQuuz, myBar, platformFoo}, []android.Module{artFragment, myFragment})
		expectedElements := java.ClasspathElements{
			expectFragmentElement(artFragment, artBaz, artQuuz),
			expectFragmentElement(myFragment, myBar),
			expectLibraryElement(platformFoo),
		}
		assertElementsEquals(t, "elements", expectedElements, elements)
	})

	// Verify that CreateClasspathElements detects when a fragment does not have an associated apex.
	t.Run("non apex fragment", func(t *testing.T) {
		ctx := newCtx()
		elements := java.CreateClasspathElements(ctx, []android.Module{}, []android.Module{nonApexFragment})
		android.FailIfNoMatchingErrors(t, "fragment non-apex-fragment{.*} is not part of an apex", ctx.errs)
		expectedElements := java.ClasspathElements{}
		assertElementsEquals(t, "elements", expectedElements, elements)
	})

	// Verify that CreateClasspathElements detects when an apex has multiple fragments.
	t.Run("multiple fragments for same apex", func(t *testing.T) {
		ctx := newCtx()
		elements := java.CreateClasspathElements(ctx, []android.Module{}, []android.Module{artFragment, artFragment})
		android.FailIfNoMatchingErrors(t, "apex com.android.art has multiple fragments, art-bootclasspath-fragment{.*} and art-bootclasspath-fragment{.*}", ctx.errs)
		expectedElements := java.ClasspathElements{}
		assertElementsEquals(t, "elements", expectedElements, elements)
	})

	// Verify that CreateClasspathElements detects when a library is in multiple fragments.
	t.Run("library from multiple fragments", func(t *testing.T) {
		ctx := newCtx()
		elements := java.CreateClasspathElements(ctx, []android.Module{other}, []android.Module{artFragment, myFragment})
		android.FailIfNoMatchingErrors(t, "library othersdklibrary{.*} is in two separate fragments, art-bootclasspath-fragment{.*} and mybootclasspath-fragment{.*}", ctx.errs)
		expectedElements := java.ClasspathElements{}
		assertElementsEquals(t, "elements", expectedElements, elements)
	})

	// Verify that CreateClasspathElements detects when a fragment's contents are not contiguous and
	// are separated by a library from another fragment.
	t.Run("discontiguous separated by fragment", func(t *testing.T) {
		ctx := newCtx()
		elements := java.CreateClasspathElements(ctx, []android.Module{artBaz, myBar, artQuuz, platformFoo}, []android.Module{artFragment, myFragment})
		expectedElements := java.ClasspathElements{
			expectFragmentElement(artFragment, artBaz, artQuuz),
			expectFragmentElement(myFragment, myBar),
			expectLibraryElement(platformFoo),
		}
		assertElementsEquals(t, "elements", expectedElements, elements)
		android.FailIfNoMatchingErrors(t, "libraries from the same fragment must be contiguous, however baz{.*} and quuz{os:android,arch:common,apex:apex10000} from fragment art-bootclasspath-fragment{.*} are separated by libraries from fragment mybootclasspath-fragment{.*} like bar{.*}", ctx.errs)
	})

	// Verify that CreateClasspathElements detects when a fragment's contents are not contiguous and
	// are separated by a standalone library.
	t.Run("discontiguous separated by library", func(t *testing.T) {
		ctx := newCtx()
		elements := java.CreateClasspathElements(ctx, []android.Module{artBaz, platformFoo, artQuuz, myBar}, []android.Module{artFragment, myFragment})
		expectedElements := java.ClasspathElements{
			expectFragmentElement(artFragment, artBaz, artQuuz),
			expectLibraryElement(platformFoo),
			expectFragmentElement(myFragment, myBar),
		}
		assertElementsEquals(t, "elements", expectedElements, elements)
		android.FailIfNoMatchingErrors(t, "libraries from the same fragment must be contiguous, however baz{.*} and quuz{os:android,arch:common,apex:apex10000} from fragment art-bootclasspath-fragment{.*} are separated by library quuz{.*}", ctx.errs)
	})

	// Verify that CreateClasspathElements detects when there a library on the classpath that
	// indicates it is from an apex the supplied fragments list does not contain a fragment for that
	// apex.
	t.Run("no fragment for apex", func(t *testing.T) {
		ctx := newCtx()
		elements := java.CreateClasspathElements(ctx, []android.Module{artBaz, otherApexLibrary}, []android.Module{artFragment})
		expectedElements := java.ClasspathElements{
			expectFragmentElement(artFragment, artBaz),
		}
		assertElementsEquals(t, "elements", expectedElements, elements)
		android.FailIfNoMatchingErrors(t, `library otherapexlibrary{.*} is from apexes \[otherapex\] which have no corresponding fragment in \[art-bootclasspath-fragment{.*}\]`, ctx.errs)
	})
}
