// Copyright (C) 2019 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 aidl

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"testing"

	"github.com/google/blueprint"
	"github.com/google/blueprint/proptools"

	"android/soong/android"
	"android/soong/cc"
	"android/soong/genrule"
	"android/soong/java"
	"android/soong/rust"
)

func TestMain(m *testing.M) {
	os.Exit(m.Run())
}

func withFiles(files map[string][]byte) android.FixturePreparer {
	return android.FixtureMergeMockFs(files)
}

func intPtr(v int) *int {
	return &v
}

func setReleaseEnv() android.FixturePreparer {
	return android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
		// Q is finalized as 29. No codename that is actively being developed.
		variables.Platform_sdk_version = intPtr(29)
		variables.Platform_sdk_codename = proptools.StringPtr("REL")
		variables.Platform_sdk_final = proptools.BoolPtr(true)
		variables.Platform_version_active_codenames = []string{}
	})
}

func setTestFreezeEnv() android.FixturePreparer {
	return android.FixtureMergeEnv(map[string]string{
		"AIDL_FROZEN_REL":    "true",
		"AIDL_FROZEN_OWNERS": "aosp test",
	})
}

func setTransitiveFreezeEnv() android.FixturePreparer {
	return android.FixtureMergeEnv(map[string]string{
		"AIDL_TRANSITIVE_FREEZE": "true",
	})
}

func _testAidl(t *testing.T, bp string, customizers ...android.FixturePreparer) android.FixturePreparer {
	t.Helper()

	preparers := []android.FixturePreparer{}

	preparers = append(preparers,
		cc.PrepareForTestWithCcDefaultModules,
		java.PrepareForTestWithJavaDefaultModules,
		genrule.PrepareForTestWithGenRuleBuildComponents,
		android.PrepareForTestWithNamespace,
	)

	bp = bp + `
		package {
			default_visibility: ["//visibility:public"],
		}
		java_defaults {
			name: "aidl-java-module-defaults",
		}
		cc_defaults {
			name: "aidl-cpp-module-defaults",
		}
		rust_defaults {
			name: "aidl-rust-module-defaults",
		}
		cc_library {
			name: "libbinder",
			recovery_available: true,
		}
		cc_library {
			name: "libutils",
			recovery_available: true,
		}
		cc_library {
			name: "libcutils",
		}
		cc_library {
			name: "libbinder_ndk",
			recovery_available: true,
			stubs: {
				versions: ["29"],
			}
		}
		ndk_library {
			name: "libbinder_ndk",
			symbol_file: "libbinder_ndk.map.txt",
			first_version: "29",
		}
		cc_library {
			name: "liblog",
			no_libcrt: true,
			nocrt: true,
			system_shared_libs: [],
		}
		rust_library {
			name: "libstd",
			crate_name: "std",
			srcs: [""],
			no_stdlibs: true,
			sysroot: true,
		}
		rust_library {
			name: "libtest",
			crate_name: "test",
			srcs: [""],
			no_stdlibs: true,
			sysroot: true,
		}
		rust_library {
			name: "liblazy_static",
			crate_name: "lazy_static",
			srcs: [""],
		}
		rust_library {
			name: "libbinder_rs",
			crate_name: "binder",
			srcs: [""],
		}
		rust_proc_macro {
			name: "libasync_trait",
			crate_name: "async_trait",
			srcs: [""],
			no_stdlibs: true,
		}
	`
	preparers = append(preparers, android.FixtureWithRootAndroidBp(bp))
	preparers = append(preparers, android.FixtureAddTextFile("system/tools/aidl/build/Android.bp", `
		aidl_interfaces_metadata {
			name: "aidl_metadata_json",
			visibility: ["//system/tools/aidl:__subpackages__"],
		}
	`))

	preparers = append(preparers, android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
		// To keep tests stable, fix Platform_sdk_codename and Platform_sdk_final
		// Use setReleaseEnv() to test release version
		variables.Platform_sdk_version = intPtr(28)
		variables.Platform_sdk_codename = proptools.StringPtr("Q")
		variables.Platform_version_active_codenames = []string{"Q"}
		variables.Platform_sdk_final = proptools.BoolPtr(false)
	}))

	preparers = append(preparers, customizers...)

	preparers = append(preparers,
		rust.PrepareForTestWithRustBuildComponents,
		android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
			ctx.RegisterModuleType("aidl_interface", aidlInterfaceFactory)
			ctx.RegisterModuleType("aidl_interfaces_metadata", aidlInterfacesMetadataSingletonFactory)
			ctx.RegisterModuleType("rust_defaults", func() android.Module {
				return rust.DefaultsFactory()
			})
			ctx.PreArchMutators(registerPreArchMutators)
			ctx.PostDepsMutators(registerPostDepsMutators)
		}),
	)

	return android.GroupFixturePreparers(preparers...)
}

func testAidl(t *testing.T, bp string, customizers ...android.FixturePreparer) (*android.TestContext, android.Config) {
	t.Helper()
	preparer := _testAidl(t, bp, customizers...)
	result := preparer.RunTest(t)
	return result.TestContext, result.Config
}

func testAidlError(t *testing.T, pattern, bp string, customizers ...android.FixturePreparer) {
	t.Helper()
	preparer := _testAidl(t, bp, customizers...)
	preparer.
		ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)).
		RunTest(t)
}

// asserts that there are expected module regardless of variants
func assertModulesExists(t *testing.T, ctx *android.TestContext, names ...string) {
	t.Helper()
	missing := []string{}
	for _, name := range names {
		variants := ctx.ModuleVariantsForTests(name)
		if len(variants) == 0 {
			missing = append(missing, name)
		}
	}
	if len(missing) > 0 {
		// find all the modules that do exist
		allModuleNames := make(map[string]bool)
		ctx.VisitAllModules(func(m blueprint.Module) {
			allModuleNames[ctx.ModuleName(m)] = true
		})
		t.Errorf("expected modules(%v) not found. all modules: %v", missing, android.SortedStringKeys(allModuleNames))
	}
}

func assertContains(t *testing.T, actual, expected string) {
	t.Helper()
	if !strings.Contains(actual, expected) {
		t.Errorf("%q is not found in %q.", expected, actual)
	}
}

func assertListContains(t *testing.T, actual []string, expected string) {
	t.Helper()
	for _, a := range actual {
		if strings.Contains(a, expected) {
			return
		}
	}
	t.Errorf("%q is not found in %v.", expected, actual)
}

// Vintf module must have versions in release version
func TestVintfWithoutVersionInRelease(t *testing.T) {
	vintfWithoutVersionBp := `
	aidl_interface {
		name: "foo",
		stability: "vintf",
		srcs: [
			"IFoo.aidl",
		],
		backend: {
			rust: {
				enabled: true,
			},
		},
	}`
	expectedError := `module "foo_interface": versions: must be set \(need to be frozen\) when "unstable" is false, PLATFORM_VERSION_CODENAME is REL, and "owner" property is missing.`
	testAidlError(t, expectedError, vintfWithoutVersionBp, setReleaseEnv())
	testAidlError(t, expectedError, vintfWithoutVersionBp, setTestFreezeEnv())

	ctx, _ := testAidl(t, vintfWithoutVersionBp)
	assertModulesExists(t, ctx, "foo-V1-java", "foo-V1-rust", "foo-V1-cpp", "foo-V1-ndk")
}

// Check if using unstable version in release cause an error.
func TestUnstableVersionUsageInRelease(t *testing.T) {
	unstableVersionUsageInJavaBp := `
	aidl_interface {
		name: "foo",
		versions: [
			"1",
		],
		srcs: [
			"IFoo.aidl",
		],
	}
	java_library {
		name: "bar",
		libs: ["foo-V2-java"],
	}`
	files := withFiles(map[string][]byte{
		"aidl_api/foo/1/foo.1.aidl": nil,
		"aidl_api/foo/1/.hash":      nil,
	})

	expectedError := `foo-V2-java is disallowed in release version because it is unstable.`
	testAidlError(t, expectedError, unstableVersionUsageInJavaBp, setReleaseEnv(), files)
	testAidlError(t, expectedError, unstableVersionUsageInJavaBp, setTestFreezeEnv(), files)
	testAidl(t, unstableVersionUsageInJavaBp, files)

	// A stable version can be used in release version
	stableVersionUsageInJavaBp := `
	aidl_interface {
		name: "foo",
		versions: [
			"1",
		],
		srcs: [
			"IFoo.aidl",
		],
	}
	java_library {
		name: "bar",
		libs: ["foo-V1-java"],
	}`

	testAidl(t, stableVersionUsageInJavaBp, setReleaseEnv(), files)
	testAidl(t, stableVersionUsageInJavaBp, setTestFreezeEnv(), files)
	testAidl(t, stableVersionUsageInJavaBp, files)
}

func TestUsingUnstableVersionIndirectlyInRelease(t *testing.T) {
	unstableVersionUsageInJavaBp := `
	aidl_interface {
		name: "xxx",
		srcs: ["IFoo.aidl"],
		versions: ["1"],
	}
	aidl_interface {
		name: "foo",
		imports: ["xxx-V2"],    // not OK
		versions: ["1"],
		srcs: ["IFoo.aidl"],
	}
	java_library {
		name: "bar",
		libs: ["foo-V1-java"],  // OK
	}`
	files := withFiles(map[string][]byte{
		"aidl_api/foo/1/foo.1.aidl": nil,
		"aidl_api/foo/1/.hash":      nil,
		"aidl_api/xxx/1/foo.1.aidl": nil,
		"aidl_api/xxx/1/.hash":      nil,
	})

	expectedError := `xxx-V2-java is disallowed in release version because it is unstable.`
	testAidlError(t, expectedError, unstableVersionUsageInJavaBp, setReleaseEnv(), files)
	testAidlError(t, expectedError, unstableVersionUsageInJavaBp, setTestFreezeEnv(), files)
	testAidl(t, unstableVersionUsageInJavaBp, files)
}

// The module which has never been frozen and is not "unstable" is not allowed in release version.
func TestNonVersionedModuleUsageInRelease(t *testing.T) {
	nonVersionedModuleUsageInJavaBp := `
	aidl_interface {
		name: "foo",
		srcs: [
			"IFoo.aidl",
		],
	}

	java_library {
		name: "bar",
		libs: ["foo-V1-java"],
	}`

	expectedError := `"foo_interface": versions: must be set \(need to be frozen\) when "unstable" is false, PLATFORM_VERSION_CODENAME is REL, and "owner" property is missing.`
	testAidlError(t, expectedError, nonVersionedModuleUsageInJavaBp, setReleaseEnv())
	testAidlError(t, expectedError, nonVersionedModuleUsageInJavaBp, setTestFreezeEnv())
	testAidl(t, nonVersionedModuleUsageInJavaBp)

	nonVersionedUnstableModuleUsageInJavaBp := `
	aidl_interface {
		name: "foo",
		srcs: [
			"IFoo.aidl",
		],
		unstable: true,
	}

	java_library {
		name: "bar",
		libs: ["foo-java"],
	}`

	testAidl(t, nonVersionedUnstableModuleUsageInJavaBp, setReleaseEnv())
	testAidl(t, nonVersionedUnstableModuleUsageInJavaBp, setTestFreezeEnv())
	testAidl(t, nonVersionedUnstableModuleUsageInJavaBp)
}

func TestNonVersionedModuleOwnedByTestUsageInRelease(t *testing.T) {
	nonVersionedModuleUsageInJavaBp := `
	aidl_interface {
		name: "foo",
		owner: "test",
		srcs: [
			"IFoo.aidl",
		],
	}

	java_library {
		name: "bar",
		libs: ["foo-V1-java"],
	}`

	expectedError := `"foo_interface": versions: must be set \(need to be frozen\) when "unstable" is false, PLATFORM_VERSION_CODENAME is REL, and "owner" property is missing.`
	testAidl(t, nonVersionedModuleUsageInJavaBp, setReleaseEnv())
	testAidlError(t, expectedError, nonVersionedModuleUsageInJavaBp, setTestFreezeEnv())
	testAidl(t, nonVersionedModuleUsageInJavaBp)
}

func TestNonVersionedModuleOwnedByOtherUsageInRelease(t *testing.T) {
	nonVersionedModuleUsageInJavaBp := `
	aidl_interface {
		name: "foo",
		owner: "unknown-owner",
		srcs: [
			"IFoo.aidl",
		],
	}

	java_library {
		name: "bar",
		libs: ["foo-V1-java"],
	}`

	testAidl(t, nonVersionedModuleUsageInJavaBp, setReleaseEnv())
	testAidl(t, nonVersionedModuleUsageInJavaBp, setTestFreezeEnv())
	testAidl(t, nonVersionedModuleUsageInJavaBp)
}

func TestImportInRelease(t *testing.T) {
	importInRelease := `
	aidl_interface {
		name: "foo",
		srcs: [
			"IFoo.aidl",
		],
		imports: ["bar-V1"],
		versions: ["1"],
	}

	aidl_interface {
		name: "bar",
		srcs: [
			"IBar.aidl",
		],
		versions: ["1"],
	}
	`
	files := withFiles(map[string][]byte{
		"aidl_api/foo/1/foo.1.aidl": nil,
		"aidl_api/foo/1/.hash":      nil,
		"aidl_api/bar/1/bar.1.aidl": nil,
		"aidl_api/bar/1/.hash":      nil,
	})

	testAidl(t, importInRelease, setReleaseEnv(), files)
	testAidl(t, importInRelease, setTestFreezeEnv(), files)
	testAidl(t, importInRelease, files)
}

func TestUnstableVersionedModuleUsageInRelease(t *testing.T) {
	nonVersionedModuleUsageInJavaBp := `
	aidl_interface {
		name: "foo",
		srcs: [
			"IFoo.aidl",
		],
		versions: ["1"],
	}

	java_library {
		name: "bar",
		libs: ["foo-V2-java"],
	}`

	expectedError := `Android.bp:10:2: module \"bar\" variant \"android_common\": foo-V2-java is disallowed in release version because it is unstable, and its \"owner\" property is missing.`
	testAidlError(t, expectedError, nonVersionedModuleUsageInJavaBp, setReleaseEnv())
	testAidlError(t, expectedError, nonVersionedModuleUsageInJavaBp, setTestFreezeEnv())
	testAidl(t, nonVersionedModuleUsageInJavaBp, withFiles(map[string][]byte{
		"aidl_api/foo/1/foo.1.aidl": nil,
		"aidl_api/foo/1/.hash":      nil,
	}))
}

func TestUnstableVersionedModuleOwnedByTestUsageInRelease(t *testing.T) {
	nonVersionedModuleUsageInJavaBp := `
	aidl_interface {
		name: "foo",
		owner: "test",
		srcs: [
			"IFoo.aidl",
		],
		versions: ["1"],
	}

	java_library {
		name: "bar",
		libs: ["foo-V2-java"],
	}`
	files := withFiles(map[string][]byte{
		"aidl_api/foo/1/foo.1.aidl": nil,
		"aidl_api/foo/1/.hash":      nil,
	})

	expectedError := `Android.bp:11:2: module \"bar\" variant \"android_common\": foo-V2-java is disallowed in release version because it is unstable, and its \"owner\" property is missing.`
	testAidl(t, nonVersionedModuleUsageInJavaBp, setReleaseEnv(), files)
	testAidlError(t, expectedError, nonVersionedModuleUsageInJavaBp, setTestFreezeEnv(), files)
	testAidl(t, nonVersionedModuleUsageInJavaBp, files)
}

func TestUnstableVersionedModuleOwnedByOtherUsageInRelease(t *testing.T) {
	nonVersionedModuleUsageInJavaBp := `
	aidl_interface {
		name: "foo",
		owner: "unknown-owner",
		srcs: [
			"IFoo.aidl",
		],
		versions: ["1"],
	}

	java_library {
		name: "bar",
		libs: ["foo-V2-java"],
	}`
	files := withFiles(map[string][]byte{
		"aidl_api/foo/1/foo.1.aidl": nil,
		"aidl_api/foo/1/.hash":      nil,
	})

	testAidl(t, nonVersionedModuleUsageInJavaBp, setReleaseEnv(), files)
	testAidl(t, nonVersionedModuleUsageInJavaBp, setTestFreezeEnv(), files)
	testAidl(t, nonVersionedModuleUsageInJavaBp, files)
}

func TestUnstableModules(t *testing.T) {
	testAidlError(t, `module "foo_interface": stability: must be empty when "unstable" is true`, `
		aidl_interface {
			name: "foo",
			stability: "vintf",
			unstable: true,
			srcs: [
				"IFoo.aidl",
			],
			backend: {
				rust: {
					enabled: true,
				},
			},
		}
	`)

	testAidlError(t, `module "foo_interface": versions: cannot have versions for an unstable interface`, `
		aidl_interface {
			name: "foo",
			versions: [
				"1",
			],
			unstable: true,
			srcs: [
				"IFoo.aidl",
			],
			backend: {
				rust: {
					enabled: true,
				},
			},
		}
	`)

	ctx, _ := testAidl(t, `
		aidl_interface {
			name: "foo",
			unstable: true,
			srcs: [
				"IFoo.aidl",
			],
			backend: {
				rust: {
					enabled: true,
				},
			},
		}
	`)

	assertModulesExists(t, ctx, "foo-java", "foo-rust", "foo-cpp", "foo-ndk")
}

func TestCreatesModulesWithNoVersions(t *testing.T) {
	ctx, _ := testAidl(t, `
		aidl_interface {
			name: "foo",
			srcs: [
				"IFoo.aidl",
			],
			backend: {
				rust: {
					enabled: true,
				},
			},
		}
	`)

	assertModulesExists(t, ctx, "foo-V1-java", "foo-V1-rust", "foo-V1-cpp", "foo-V1-ndk")
}

func TestCreatesModulesWithFrozenVersions(t *testing.T) {
	// Each version should be under aidl_api/<name>/<ver>
	testAidlError(t, `No sources for a previous version in aidl_api/foo/1. Was a version manually added to .bp file?`, `
		aidl_interface {
			name: "foo",
			srcs: [
				"IFoo.aidl",
			],
			versions: [
				"1",
			],
			backend: {
				rust: {
					enabled: true,
				},
			},
		}
	`)

	ctx, _ := testAidl(t, `
		aidl_interface {
			name: "foo",
			srcs: [
				"IFoo.aidl",
			],
			versions: [
				"1",
			],
			backend: {
				rust: {
					enabled: true,
				},
			},
		}
	`, withFiles(map[string][]byte{
		"aidl_api/foo/1/foo.1.aidl": nil,
		"aidl_api/foo/1/.hash":      nil,
	}))

	// For frozen version "1"
	assertModulesExists(t, ctx, "foo-V1-java", "foo-V1-rust", "foo-V1-cpp", "foo-V1-ndk")

	// For ToT (current)
	assertModulesExists(t, ctx, "foo-V2-java", "foo-V2-rust", "foo-V2-cpp", "foo-V2-ndk")
}

func TestErrorsWithUnsortedVersions(t *testing.T) {
	testAidlError(t, `versions: should be sorted`, `
		aidl_interface {
			name: "foo",
			srcs: [
				"IFoo.aidl",
			],
			versions: [
				"2",
				"1",
			],
			backend: {
				rust: {
					enabled: true,
				},
			},
		}
	`)
}

func TestErrorsWithDuplicateVersions(t *testing.T) {
	testAidlError(t, `versions: duplicate`, `
		aidl_interface {
			name: "foo",
			srcs: [
				"IFoo.aidl",
			],
			versions: [
				"1",
				"1",
			],
		}
	`)
}

func TestErrorsWithNonPositiveVersions(t *testing.T) {
	testAidlError(t, `versions: should be > 0`, `
		aidl_interface {
			name: "foo",
			srcs: [
				"IFoo.aidl",
			],
			versions: [
				"-1",
				"1",
			],
		}
	`)
}

func TestErrorsWithNonIntegerVersions(t *testing.T) {
	testAidlError(t, `versions: "first" is not an integer`, `
		aidl_interface {
			name: "foo",
			srcs: [
				"IFoo.aidl",
			],
			versions: [
				"first",
			],
		}
	`)
}

const (
	androidVariant    = "android_common"
	nativeVariant     = "android_arm_armv7-a-neon_shared"
	nativeRustVariant = "android_arm_armv7-a-neon_dylib"
)

func TestNativeOutputIsAlwaysVersioned(t *testing.T) {
	var ctx *android.TestContext
	assertOutput := func(moduleName, variant, outputFilename string) {
		t.Helper()
		producer, ok := ctx.ModuleForTests(moduleName, variant).Module().(android.OutputFileProducer)
		if !ok {
			t.Errorf("%s(%s): should be OutputFileProducer.", moduleName, variant)
		}
		paths, err := producer.OutputFiles("")
		if err != nil {
			t.Errorf("%s(%s): failed to get OutputFiles: %v", moduleName, variant, err)
		}
		if len(paths) != 1 || paths[0].Base() != outputFilename {
			t.Errorf("%s(%s): expected output %q, but got %v", moduleName, variant, outputFilename, paths)
		}
	}

	// No versions
	ctx, _ = testAidl(t, `
		aidl_interface {
			name: "foo",
			srcs: [
				"IFoo.aidl",
			],
			backend: {
				rust: {
					enabled: true,
				},
			},
		}
	`)
	// Even though there is no version, generated modules have version(V1) unless it isn't an unstable interface.
	assertOutput("foo-V1-java", androidVariant, "foo-V1-java.jar")

	assertOutput("foo-V1-cpp", nativeVariant, "foo-V1-cpp.so")
	assertOutput("foo-V1-rust", nativeRustVariant, "libfoo_V1.dylib.so")

	// With versions: "1", "2"
	ctx, _ = testAidl(t, `
		aidl_interface {
			name: "foo",
			srcs: [
				"IFoo.aidl",
			],
			versions: [
				"1", "2",
			],
			backend: {
				rust: {
					enabled: true,
				},
			},
		}
	`, withFiles(map[string][]byte{
		"aidl_api/foo/1/foo.1.aidl": nil,
		"aidl_api/foo/1/.hash":      nil,
		"aidl_api/foo/2/foo.2.aidl": nil,
		"aidl_api/foo/2/.hash":      nil,
	}))

	// alias for the latest frozen version (=2)
	assertOutput("foo-V2-java", androidVariant, "foo-V2-java.jar")
	assertOutput("foo-V2-cpp", nativeVariant, "foo-V2-cpp.so")
	assertOutput("foo-V2-rust", nativeRustVariant, "libfoo_V2.dylib.so")

	// frozen "1"
	assertOutput("foo-V1-java", androidVariant, "foo-V1-java.jar")
	assertOutput("foo-V1-cpp", nativeVariant, "foo-V1-cpp.so")
	assertOutput("foo-V1-rust", nativeRustVariant, "libfoo_V1.dylib.so")

	// tot
	assertOutput("foo-V3-java", androidVariant, "foo-V3-java.jar")
	assertOutput("foo-V3-cpp", nativeVariant, "foo-V3-cpp.so")
	assertOutput("foo-V3-rust", nativeRustVariant, "libfoo_V3.dylib.so")

	// skip ndk since they follow the same rule with cpp
}

func TestImports(t *testing.T) {
	testAidlError(t, `Import does not exist:`, `
		aidl_interface {
			name: "foo",
			srcs: [
				"IFoo.aidl",
			],
			imports: [
				"bar",
			]
		}
	`)

	testAidlError(t, `backend.java.enabled: Java backend not enabled in the imported AIDL interface "bar"`, `
		aidl_interface {
			name: "foo",
			srcs: [
				"IFoo.aidl",
			],
			imports: [
				"bar-V1",
			]
		}
		aidl_interface {
			name: "bar",
			srcs: [
				"IBar.aidl",
			],
			backend: {
				java: {
					enabled: false,
				},
			},
		}
	`)

	testAidlError(t, `backend.cpp.enabled: C\+\+ backend not enabled in the imported AIDL interface "bar"`, `
		aidl_interface {
			name: "foo",
			srcs: [
				"IFoo.aidl",
			],
			imports: [
				"bar-V1",
			]
		}
		aidl_interface {
			name: "bar",
			srcs: [
				"IBar.aidl",
			],
			backend: {
				cpp: {
					enabled: false,
				},
			},
		}
	`)

	ctx, _ := testAidl(t, `
		aidl_interface {
			name: "foo",
			srcs: [
				"IFoo.aidl",
			],
			backend: {
				rust: {
					enabled: true,
				},
			},
			imports: [
				"bar.1-V1",
			]
		}
		aidl_interface {
			name: "bar.1",
			srcs: [
				"IBar.aidl",
			],
			backend: {
				rust: {
					enabled: true,
				},
			},
		}
	`)

	ldRule := ctx.ModuleForTests("foo-V1-cpp", nativeVariant).Rule("ld")
	libFlags := ldRule.Args["libFlags"]
	libBar := filepath.Join("bar.1-V1-cpp", nativeVariant, "bar.1-V1-cpp.so")
	if !strings.Contains(libFlags, libBar) {
		t.Errorf("%q is not found in %q", libBar, libFlags)
	}

	rustcRule := ctx.ModuleForTests("foo-V1-rust", nativeRustVariant).Rule("rustc")
	libFlags = rustcRule.Args["libFlags"]
	libBar = filepath.Join("out", "soong", ".intermediates", "bar.1-V1-rust", nativeRustVariant, "unstripped", "libbar_1_V1.dylib.so")
	libBarFlag := "--extern bar_1=" + libBar
	if !strings.Contains(libFlags, libBarFlag) {
		t.Errorf("%q is not found in %q", libBarFlag, libFlags)
	}
}

func TestDuplicatedVersions(t *testing.T) {
	// foo depends on myiface-V2-ndk via direct dep and also on
	// myiface-V1-ndk via indirect dep. This should be prohibited.
	testAidlError(t, `depends on multiple versions of the same aidl_interface: myiface-V1-.*, myiface-V2-.*`, `
		aidl_interface {
			name: "myiface",
			srcs: ["IFoo.aidl"],
			versions: ["1", "2"],
		}

		cc_library {
			name: "foo",
			shared_libs: ["myiface-V2-ndk", "bar"],
		}

		cc_library {
			name: "bar",
			shared_libs: ["myiface-V1-ndk"],
		}

	`, withFiles(map[string][]byte{
		"aidl_api/myiface/1/myiface.1.aidl": nil,
		"aidl_api/myiface/1/.hash":          nil,
		"aidl_api/myiface/2/myiface.2.aidl": nil,
		"aidl_api/myiface/2/.hash":          nil,
	}))
	testAidlError(t, `depends on multiple versions of the same aidl_interface: myiface-V1-.*, myiface-V2-.*`, `
		aidl_interface {
			name: "myiface",
			srcs: ["IFoo.aidl"],
			versions: ["1"],
		}

		aidl_interface {
			name: "myiface2",
			srcs: ["IBar.aidl"],
			imports: ["myiface-V2"]
		}

		cc_library {
			name: "foobar",
			shared_libs: ["myiface-V1-ndk", "myiface2-V1-ndk"],
		}

	`, withFiles(map[string][]byte{
		"aidl_api/myiface/1/myiface.1.aidl": nil,
		"aidl_api/myiface/1/.hash":          nil,
	}))
	testAidlError(t, `depends on multiple versions of the same aidl_interface: myiface-V1-.*, myiface-V2-.*`, `
		aidl_interface {
			name: "myiface",
			srcs: ["IFoo.aidl"],
			versions: ["1"],
		}

		aidl_interface {
			name: "myiface2",
			srcs: ["IBar.aidl"],
			imports: ["myiface-V2"]
		}

		cc_library {
			name: "foobar",
			srcs: [":myiface-V1-ndk-source"],
			shared_libs: ["myiface2-V1-ndk"],
		}

	`, withFiles(map[string][]byte{
		"aidl_api/myiface/1/myiface.1.aidl": nil,
		"aidl_api/myiface/1/.hash":          nil,
	}))
	// Okay to reference two different
	testAidl(t, `
		aidl_interface {
			name: "myiface",
			srcs: ["IFoo.aidl"],
			versions: ["1"],
		}
		cc_library {
			name: "foobar",
			shared_libs: ["myiface-V1-cpp", "myiface-V1-ndk"],
		}
	`, withFiles(map[string][]byte{
		"aidl_api/myiface/1/myiface.1.aidl": nil,
		"aidl_api/myiface/1/.hash":          nil,
	}))
	testAidl(t, `
		aidl_interface {
			name: "myiface",
			srcs: ["IFoo.aidl"],
			versions: ["1"],
		}

		aidl_interface {
			name: "myiface2",
			srcs: ["IBar.aidl"],
			imports: ["myiface-V2"]
		}

		cc_library {
			name: "foobar",
			srcs: [":myiface-V2-ndk-source"],
			shared_libs: ["myiface2-V1-ndk"],
		}

	`, withFiles(map[string][]byte{
		"aidl_api/myiface/1/myiface.1.aidl": nil,
		"aidl_api/myiface/1/.hash":          nil,
	}))
	testAidl(t, `
		aidl_interface {
			name: "myiface",
			srcs: ["IFoo.aidl"],
			versions: ["1"],
		}

		aidl_interface {
			name: "myiface2",
			srcs: ["IBar.aidl"],
			imports: ["myiface-V2"]
		}

		cc_library {
			name: "foobar",
			shared_libs: ["myiface-V2-ndk", "myiface2-V1-ndk"],
		}

	`, withFiles(map[string][]byte{
		"aidl_api/myiface/1/myiface.1.aidl": nil,
		"aidl_api/myiface/1/.hash":          nil,
	}))
}

func TestUnstableVndkModule(t *testing.T) {
	testAidlError(t, `module "myiface_interface": stability: must be "vintf" if the module is for VNDK.`, `
		aidl_interface {
			name: "myiface",
			srcs: ["IFoo.aidl"],
			vendor_available: true,
			product_available: true,
			unstable: true,
			vndk: {
				enabled: true,
			},
		}
	`)
	testAidlError(t, `module "myiface_interface": stability: must be "vintf" if the module is for VNDK.`, `
		aidl_interface {
			name: "myiface",
			vendor_available: true,
			product_available: true,
			srcs: ["IFoo.aidl"],
			vndk: {
				enabled: true,
			},
		}
	`)
	testAidl(t, `
		aidl_interface {
			name: "myiface",
			vendor_available: true,
			product_available: true,
			srcs: ["IFoo.aidl"],
			stability: "vintf",
			vndk: {
				enabled: true,
			},
		}
	`)
}

func TestRecoveryAvailable(t *testing.T) {
	ctx, _ := testAidl(t, `
		aidl_interface {
			name: "myiface",
			recovery_available: true,
			srcs: ["IFoo.aidl"],
		}
	`)
	ctx.ModuleForTests("myiface-V1-ndk", "android_recovery_arm64_armv8-a_shared")
	ctx.ModuleForTests("myiface-V1-cpp", "android_recovery_arm64_armv8-a_shared")
}

func TestRustDuplicateNames(t *testing.T) {
	testAidl(t, `
		aidl_interface {
			name: "myiface",
			srcs: ["dir/a/Foo.aidl", "dir/b/Foo.aidl"],
			backend: {
				rust: {
					enabled: true,
				},
			},
		}
	`)
}

func TestAidlImportFlagsForImportedModules(t *testing.T) {
	customizer := withFiles(map[string][]byte{
		"foo/Android.bp": []byte(`
			aidl_interface {
				name: "foo-iface",
				srcs: ["a/Foo.aidl"],
				imports: ["bar-iface-V2"],
				versions: ["1"],
			}
		`),
		"foo/a/Foo.aidl": nil,
		"foo/aidl_api/foo-iface/current/a/Foo.aidl": nil,
		"foo/aidl_api/foo-iface/1/a/Foo.aidl":       nil,
		"foo/aidl_api/foo-iface/1/.hash":            nil,

		"bar/Android.bp": []byte(`
			aidl_interface {
				name: "bar-iface",
				srcs: ["b/Bar.aidl"],
				imports: ["baz-iface-V1"],
				versions: ["1"],
			}
		`),
		"bar/b/Bar.aidl": nil,
		"bar/aidl_api/bar-iface/current/b/Bar.aidl": nil,
		"bar/aidl_api/bar-iface/1/b/Bar.aidl":       nil,
		"bar/aidl_api/bar-iface/1/.hash":            nil,

		"baz/Android.bp": []byte(`
			aidl_interface {
				name: "baz-iface",
				srcs: ["b/Baz.aidl"],
				include_dirs: ["baz-include"],
				versions: ["1"],
			}
		`),
		"baz/b/Baz.aidl": nil,
		"baz/aidl_api/baz-iface/current/b/Baz.aidl": nil,
		"baz/aidl_api/baz-iface/1/b/Baz.aidl":       nil,
		"baz/aidl_api/baz-iface/1/.hash":            nil,
	})
	ctx, _ := testAidl(t, ``, customizer)

	// checkapidump rule is to compare "compatibility" between ToT(dump) and "current"
	{
		rule := ctx.ModuleForTests("foo-iface-api", "").Output("checkapi_dump.timestamp")
		android.AssertStringEquals(t, "checkapi(dump == current) imports", "", rule.Args["imports"])
		android.AssertStringDoesContain(t, "checkapi(dump == current) optionalFlags",
			rule.Args["optionalFlags"],
			"-pout/soong/.intermediates/bar/bar-iface_interface/2/preprocessed.aidl")
	}

	// has_development rule runs --checkapi for equality between latest("1")
	// and ToT
	{
		rule := ctx.ModuleForTests("foo-iface-api", "").Output("has_development")
		android.AssertStringDoesContain(t, "checkapi(dump == latest(1)) should import import's preprocessed",
			rule.RuleParams.Command,
			"-pout/soong/.intermediates/bar/bar-iface_interface/2/preprocessed.aidl")
	}

	// compile (v1)
	{
		rule := ctx.ModuleForTests("foo-iface-V1-cpp-source", "").Output("a/Foo.cpp")
		android.AssertStringEquals(t, "compile(old=1) should import aidl_api/1", "-Ifoo/aidl_api/foo-iface/1", rule.Args["imports"])
		android.AssertStringDoesContain(t, "compile(old=1) should import bar.preprocessed",
			rule.Args["optionalFlags"],
			"-pout/soong/.intermediates/bar/bar-iface_interface/2/preprocessed.aidl")
	}
	// compile ToT(v2)
	{
		rule := ctx.ModuleForTests("foo-iface-V2-cpp-source", "").Output("a/Foo.cpp")
		android.AssertStringEquals(t, "compile(tot=2) should import base dirs of srcs", "-Ifoo", rule.Args["imports"])
		android.AssertStringDoesContain(t, "compile(tot=2) should import bar.preprocessed",
			rule.Args["optionalFlags"],
			"-pout/soong/.intermediates/bar/bar-iface_interface/2/preprocessed.aidl")
	}
}

func TestAidlPreprocess(t *testing.T) {
	customizer := withFiles(map[string][]byte{
		"foo/Android.bp": []byte(`
			aidl_interface {
				name: "foo-iface",
				local_include_dir: "src",
				include_dirs: [
						"path1",
						"path2/sub",
				],
				srcs: [
						"src/foo/Foo.aidl",
				],
				imports: [
					"bar-iface",
				],
				unstable: true,
			}
			aidl_interface {
				name: "bar-iface",
				local_include_dir: "src",
				srcs: [
						"src/bar/Bar.aidl",
				],
				unstable: true,
			}
		`),
		"foo/src/foo/Foo.aidl": nil,
		"foo/src/bar/Bar.aidl": nil,
	})
	ctx, _ := testAidl(t, ``, customizer)

	rule := ctx.ModuleForTests("foo-iface_interface", "").Output("preprocessed.aidl")
	android.AssertStringDoesContain(t, "preprocessing should import srcs and include_dirs",
		rule.RuleParams.Command,
		"-Ifoo/src -Ipath1 -Ipath2/sub")
	android.AssertStringDoesContain(t, "preprocessing should import import's preprocess",
		rule.RuleParams.Command,
		"-pout/soong/.intermediates/foo/bar-iface_interface/preprocessed.aidl")
}

func TestAidlImportFlagsForUnstable(t *testing.T) {
	customizer := withFiles(map[string][]byte{
		"foo/Android.bp": []byte(`
			aidl_interface {
				name: "foo-iface",
				local_include_dir: "src",
				include_dirs: [
						"path1",
						"path2/sub",
				],
				srcs: [
						"src/foo/Foo.aidl",
				],
				imports: [
					"bar-iface",
				],
				unstable: true,
			}
			aidl_interface {
				name: "bar-iface",
				local_include_dir: "src",
				srcs: [
						"src/bar/Bar.aidl",
				],
				unstable: true,
			}
		`),
		"foo/src/foo/Foo.aidl": nil,
		"foo/src/bar/Bar.aidl": nil,
	})
	ctx, _ := testAidl(t, ``, customizer)

	rule := ctx.ModuleForTests("foo-iface-cpp-source", "").Output("foo/Foo.cpp")
	android.AssertStringEquals(t, "compile(unstable) should import foo/base_dirs(target) and bar/base_dirs(imported)",
		"-Ifoo/src -Ipath1 -Ipath2/sub",
		rule.Args["imports"])
	android.AssertStringDoesContain(t, "compile(unstable) should import bar.preprocessed",
		rule.Args["optionalFlags"],
		"-pout/soong/.intermediates/foo/bar-iface_interface/preprocessed.aidl")
}

func TestSupportsGenruleAndFilegroup(t *testing.T) {
	customizer := withFiles(map[string][]byte{
		"foo/Android.bp": []byte(`
			aidl_interface {
				name: "foo-iface",
				local_include_dir: "src",
				include_dirs: [
						"path1",
						"path2/sub",
				],
				srcs: [
						"src/foo/Foo.aidl",
						":filegroup1",
						":gen1",
				],
				imports: [
						"bar-iface-V1",
				],
				versions: ["1"],
			}
			filegroup {
				name: "filegroup1",
				path: "filegroup/sub",
				srcs: [
						"filegroup/sub/pkg/Bar.aidl",
				],
			}
			genrule {
				name: "gen1",
				cmd: "generate baz/Baz.aidl",
				out: [
					"baz/Baz.aidl",
				]
			}
			aidl_interface {
				name: "bar-iface",
				local_include_dir: "src",
				srcs: [
						"src/bar/Bar.aidl",
						":gen-bar",
				],
			}
			genrule {
				name: "gen-bar",
				cmd: "generate gen/GenBar.aidl",
				out: [
					"gen/GenBar.aidl",
				]
			}
		`),
		"foo/aidl_api/foo-iface/1/foo/Foo.aidl": nil,
		"foo/aidl_api/foo-iface/1/.hash":        nil,
		"foo/filegroup/sub/pkg/Bar.aidl":        nil,
		"foo/src/foo/Foo.aidl":                  nil,
	})
	ctx, _ := testAidl(t, ``, customizer)

	// aidlCompile for snapshots (v1)
	{
		rule := ctx.ModuleForTests("foo-iface-V1-cpp-source", "").Output("foo/Foo.cpp")
		android.AssertStringEquals(t, "compile(1) should import foo/aidl_api/1",
			"-Ifoo/aidl_api/foo-iface/1 -Ipath1 -Ipath2/sub",
			rule.Args["imports"])
		android.AssertStringDoesContain(t, "compile(1) should import bar.preprocessed",
			rule.Args["optionalFlags"],
			"-pout/soong/.intermediates/foo/bar-iface_interface/1/preprocessed.aidl")
	}
	// aidlCompile for ToT (v2)
	{
		rule := ctx.ModuleForTests("foo-iface-V2-cpp-source", "").Output("foo/Foo.cpp")
		android.AssertStringEquals(t, "compile(tot=2) should import foo.base_dirs",
			"-Ifoo/src -Ifoo/filegroup/sub -Iout/soong/.intermediates/foo/gen1/gen -Ipath1 -Ipath2/sub",
			rule.Args["imports"])
		android.AssertStringDoesContain(t, "compile(tot=2) should import bar.preprocessed",
			rule.Args["optionalFlags"],
			"-pout/soong/.intermediates/foo/bar-iface_interface/1/preprocessed.aidl")
	}

	// dumpapi
	{
		rule := ctx.ModuleForTests("foo-iface-api", "").Rule("aidlDumpApiRule")
		android.AssertPathsRelativeToTopEquals(t, "dumpapi should dump srcs/filegroups/genrules", []string{
			"foo/src/foo/Foo.aidl",
			"foo/filegroup/sub/pkg/Bar.aidl",
			"out/soong/.intermediates/foo/gen1/gen/baz/Baz.aidl",
		}, rule.Inputs)

		dumpDir := "out/soong/.intermediates/foo/foo-iface-api/dump"
		android.AssertPathsRelativeToTopEquals(t, "dumpapi should dump with rel paths", []string{
			dumpDir + "/foo/Foo.aidl",
			dumpDir + "/pkg/Bar.aidl",
			dumpDir + "/baz/Baz.aidl",
			dumpDir + "/.hash",
		}, rule.Outputs.Paths())

		android.AssertStringEquals(t, "dumpapi should import base_dirs and include_dirs",
			"-Ifoo/src -Ifoo/filegroup/sub -Iout/soong/.intermediates/foo/gen1/gen -Ipath1 -Ipath2/sub",
			rule.Args["imports"])
		android.AssertStringDoesContain(t, "dumpapi should import bar.preprocessed",
			rule.Args["optionalFlags"],
			"-pout/soong/.intermediates/foo/bar-iface_interface/1/preprocessed.aidl")
	}
}

func TestAidlFlags(t *testing.T) {
	ctx, _ := testAidl(t, `
		aidl_interface {
			name: "myiface",
			srcs: ["a/Foo.aidl", "b/Bar.aidl"],
			flags: ["-Weverything", "-Werror"],
			backend: { rust: { enabled: true }}
		}
	`)
	for module, outputs := range map[string][]string{
		"myiface-V1-cpp-source":  {"a/Foo.h", "b/Bar.h"},
		"myiface-V1-java-source": {"a/Foo.java", "b/Bar.java"},
		"myiface-V1-ndk-source":  {"aidl/a/Foo.h", "aidl/b/Bar.h"},
		"myiface-V1-rust-source": {"a/Foo.rs", "b/Bar.rs"},
	} {
		for _, output := range outputs {
			t.Run(module+"/"+output, func(t *testing.T) {
				params := ctx.ModuleForTests(module, "").Output(output)
				assertContains(t, params.Args["optionalFlags"], "-Weverything")
				assertContains(t, params.Args["optionalFlags"], "-Werror")
			})
		}
	}
}

func TestAidlModuleJavaSdkVersionDeterminesMinSdkVersion(t *testing.T) {
	ctx, _ := testAidl(t, `
		aidl_interface {
			name: "myiface",
			srcs: ["a/Foo.aidl"],
			backend: {
				java: {
					sdk_version: "28",
				},
			},
		}
	`, java.FixtureWithPrebuiltApis(map[string][]string{"28": {"foo"}}))
	params := ctx.ModuleForTests("myiface-V1-java-source", "").Output("a/Foo.java")
	assertContains(t, params.Args["optionalFlags"], "--min_sdk_version 28")
}

func TestAidlModuleNameContainsVersion(t *testing.T) {
	testAidlError(t, "aidl_interface should not have '-V<number> suffix", `
		aidl_interface {
			name: "myiface-V2",
			srcs: ["a/Foo.aidl", "b/Bar.aidl"],
		}
	`)
	// Ugly, but okay
	testAidl(t, `
		aidl_interface {
			name: "myiface-V2aa",
			srcs: ["a/Foo.aidl", "b/Bar.aidl"],
		}
	`)
}

func TestExplicitAidlModuleImport(t *testing.T) {
	for _, importVersion := range []string{"V1", "V2"} {

		ctx, _ := testAidl(t, `
			aidl_interface {
				name: "foo",
				srcs: ["Foo.aidl"],
				versions: [
					"1",
				],
				imports: ["bar-`+importVersion+`"]
			}

			aidl_interface {
				name: "bar",
				srcs: ["Bar.aidl"],
				versions: [
					"1",
				],
			}
		`, withFiles(map[string][]byte{
			"aidl_api/foo/1/Foo.aidl": nil,
			"aidl_api/foo/1/.hash":    nil,
			"aidl_api/bar/1/Bar.aidl": nil,
			"aidl_api/bar/1/.hash":    nil,
		}))
		for _, foo := range []string{"foo-V1-cpp", "foo-V2-cpp"} {
			ldRule := ctx.ModuleForTests(foo, nativeVariant).Rule("ld")
			libFlags := ldRule.Args["libFlags"]
			libBar := filepath.Join("bar-"+importVersion+"-cpp", nativeVariant, "bar-"+importVersion+"-cpp.so")
			if !strings.Contains(libFlags, libBar) {
				t.Errorf("%q is not found in %q", libBar, libFlags)
			}

		}
	}

	testAidlError(t, "module \"foo_interface\": imports: \"foo\" depends on \"bar\" version \"3\"", `
		aidl_interface {
			name: "foo",
			srcs: ["Foo.aidl"],
			versions: [
				"1",
			],
			imports: ["bar-V3"]
		}

		aidl_interface {
			name: "bar",
			srcs: ["Bar.aidl"],
			versions: [
				"1",
			],
		}
	`, withFiles(map[string][]byte{
		"aidl_api/foo/1/Foo.aidl": nil,
		"aidl_api/foo/1/.hash":    nil,
		"aidl_api/bar/1/Bar.aidl": nil,
		"aidl_api/bar/1/.hash":    nil,
	}))
}

func TestUseVersionedPreprocessedWhenImporotedWithVersions(t *testing.T) {
	ctx, _ := testAidl(t, `
		aidl_interface {
			name: "unstable-foo",
			srcs: ["foo/Foo.aidl"],
			imports: [
					"bar-V2",
					"baz-V1",
					"unstable-bar",
			],
			unstable: true,
		}
		aidl_interface {
			name: "foo",
			srcs: ["foo/Foo.aidl"],
			imports: [
					"bar-V1",
					"baz-V1",
			],
			versions: ["1"],
		}
		aidl_interface {
			name: "foo-no-versions",
			srcs: ["foo/Foo.aidl"],
			imports: [
					"bar-V2",
			],
		}
		aidl_interface {
			name: "bar",
			srcs: ["bar/Bar.aidl"],
			versions: ["1"],
		}
		aidl_interface {
			name: "unstable-bar",
			srcs: ["bar/Bar.aidl"],
			unstable: true,
		}
		aidl_interface {
			name: "baz",
			srcs: ["baz/Baz.aidl"],
			versions: ["1"],
		}
	`, withFiles(map[string][]byte{
		"foo/Foo.aidl":                nil,
		"bar/Bar.aidl":                nil,
		"baz/Baz.aidl":                nil,
		"aidl_api/foo/1/foo/Foo.aidl": nil,
		"aidl_api/foo/1/.hash":        nil,
		"aidl_api/bar/1/bar/Bar.aidl": nil,
		"aidl_api/bar/1/.hash":        nil,
		"aidl_api/baz/1/baz/Baz.aidl": nil,
		"aidl_api/baz/1/.hash":        nil,
	}))
	{
		rule := ctx.ModuleForTests("foo-V2-java-source", "").Output("foo/Foo.java")
		android.AssertStringDoesContain(t, "foo-V2(tot) imports bar-V1 for 'bar-V1'", rule.Args["optionalFlags"],
			"-pout/soong/.intermediates/bar_interface/1/preprocessed.aidl")
		android.AssertStringDoesContain(t, "foo-V2(tot) imports baz-V1 for 'baz-V1'", rule.Args["optionalFlags"],
			"-pout/soong/.intermediates/baz_interface/1/preprocessed.aidl")
	}
	{
		rule := ctx.ModuleForTests("foo-V1-java-source", "").Output("foo/Foo.java")
		android.AssertStringDoesContain(t, "foo-V1 imports bar-V1(latest) for 'bar'", rule.Args["optionalFlags"],
			"-pout/soong/.intermediates/bar_interface/1/preprocessed.aidl")
		android.AssertStringDoesContain(t, "foo-V1 imports baz-V1 for 'baz-V1'", rule.Args["optionalFlags"],
			"-pout/soong/.intermediates/baz_interface/1/preprocessed.aidl")
	}
	{
		rule := ctx.ModuleForTests("unstable-foo-java-source", "").Output("foo/Foo.java")
		android.AssertStringDoesContain(t, "unstable-foo imports bar-V2(latest) for 'bar'", rule.Args["optionalFlags"],
			"-pout/soong/.intermediates/bar_interface/2/preprocessed.aidl")
		android.AssertStringDoesContain(t, "unstable-foo imports baz-V1 for 'baz-V1'", rule.Args["optionalFlags"],
			"-pout/soong/.intermediates/baz_interface/1/preprocessed.aidl")
		android.AssertStringDoesContain(t, "unstable-foo imports unstable-bar(ToT) for 'unstable-bar'", rule.Args["optionalFlags"],
			"-pout/soong/.intermediates/unstable-bar_interface/preprocessed.aidl")
	}
	{
		rule := ctx.ModuleForTests("foo-no-versions-V1-java-source", "").Output("foo/Foo.java")
		android.AssertStringDoesContain(t, "foo-no-versions-V1(latest) imports bar-V2(latest) for 'bar'", rule.Args["optionalFlags"],
			"-pout/soong/.intermediates/bar_interface/2/preprocessed.aidl")
	}
}

func FindModule(ctx *android.TestContext, name, variant, dir string) android.Module {
	var module android.Module
	ctx.VisitAllModules(func(m blueprint.Module) {
		if ctx.ModuleName(m) == name && ctx.ModuleSubDir(m) == variant && ctx.ModuleDir(m) == dir {
			module = m.(android.Module)
		}
	})
	if module == nil {
		m := ctx.ModuleForTests(name, variant).Module()
		panic(fmt.Errorf("failed to find module %q variant %q dir %q, but found one in %q",
			name, variant, dir, ctx.ModuleDir(m)))
	}
	return module
}

func TestDuplicateInterfacesWithTheSameNameInDifferentSoongNamespaces(t *testing.T) {
	ctx, _ := testAidl(t, ``, withFiles(map[string][]byte{
		"common/Android.bp": []byte(`
		  aidl_interface {
				name: "common",
				srcs: ["ICommon.aidl"],
				versions: ["1", "2"],
			}
		`),
		"common/aidl_api/common/1/ICommon.aidl": nil,
		"common/aidl_api/common/1/.hash":        nil,
		"common/aidl_api/common/2/ICommon.aidl": nil,
		"common/aidl_api/common/2/.hash":        nil,
		"vendor/a/Android.bp": []byte(`
			soong_namespace {}
		`),
		"vendor/a/foo/Android.bp": []byte(`
			aidl_interface {
				name: "foo",
				srcs: ["IFoo.aidl"],
				imports: ["common-V1"],
			}
		`),
		"vendor/b/Android.bp": []byte(`
			soong_namespace {}
		`),
		"vendor/b/foo/Android.bp": []byte(`
			aidl_interface {
				name: "foo",
				srcs: ["IFoo.aidl"],
				imports: ["common-V2"],
			}
		`),
	}))

	aFooV1Java := FindModule(ctx, "foo-V1-java", "android_common", "vendor/a/foo").(*java.Library)
	android.AssertStringListContains(t, "a/foo deps", aFooV1Java.CompilerDeps(), "common-V1-java")

	bFooV1Java := FindModule(ctx, "foo-V1-java", "android_common", "vendor/b/foo").(*java.Library)
	android.AssertStringListContains(t, "a/foo deps", bFooV1Java.CompilerDeps(), "common-V2-java")
}

func TestUnstableChecksForAidlInterfacesInDifferentNamespaces(t *testing.T) {
	files := withFiles(map[string][]byte{
		"vendor/a/Android.bp": []byte(`
			soong_namespace {}
		`),
		"vendor/a/foo/Android.bp": []byte(`
			aidl_interface {
				name: "foo",
				srcs: ["IFoo.aidl"],
				versions: ["1", "2"],
			}
			java_library {
				name: "bar",
				libs: ["foo-V2-java"],  // OK
			}
		`),
		"vendor/a/foo/aidl_api/foo/1/IFoo.aidl": nil,
		"vendor/a/foo/aidl_api/foo/1/.hash":     nil,
		"vendor/a/foo/aidl_api/foo/2/IFoo.aidl": nil,
		"vendor/a/foo/aidl_api/foo/2/.hash":     nil,
		"vendor/b/Android.bp": []byte(`
			soong_namespace {}
		`),
		"vendor/b/foo/Android.bp": []byte(`
			aidl_interface {
				name: "foo",
				srcs: ["IFoo.aidl"],
				versions: ["1"],
			}
			java_library {
				name: "bar",
				libs: ["foo-V1-java"],  // OK
			}
		`),
		"vendor/b/foo/aidl_api/foo/1/IFoo.aidl": nil,
		"vendor/b/foo/aidl_api/foo/1/.hash":     nil,
	})

	testAidl(t, ``, files, setReleaseEnv())
	testAidl(t, ``, files, setTestFreezeEnv())
	testAidl(t, ``, files)
}

func TestVersionsWithInfoAndVersions(t *testing.T) {
	conflictingFields := `
	aidl_interface {
		name: "foo",
		versions: [
			"1",
		],
		versions_with_info: [
			{
				version: "1",
			}
		],
	}
	`
	files := withFiles(map[string][]byte{
		"aidl_api/foo/1/foo.1.aidl": nil,
		"aidl_api/foo/1/.hash":      nil,
	})

	expectedError := `Use versions_with_info instead of versions.`
	testAidlError(t, expectedError, conflictingFields, files)
}

func TestVersionsWithInfo(t *testing.T) {
	ctx, _ := testAidl(t, ``, withFiles(map[string][]byte{
		"common/Android.bp": []byte(`
		  aidl_interface {
				name: "common",
				srcs: ["ICommon.aidl"],
				versions: ["1", "2"],
			}
		`),
		"common/aidl_api/common/1/ICommon.aidl": nil,
		"common/aidl_api/common/1/.hash":        nil,
		"common/aidl_api/common/2/ICommon.aidl": nil,
		"common/aidl_api/common/2/.hash":        nil,
		"foo/Android.bp": []byte(`
			aidl_interface {
				name: "foo",
				srcs: ["IFoo.aidl"],
				imports: ["common"],
				versions_with_info: [
					{version: "1", imports: ["common-V1"]},
					{version: "2", imports: ["common-V2"]},
				]
			}
		`),
		"foo/aidl_api/foo/1/IFoo.aidl": nil,
		"foo/aidl_api/foo/1/.hash":     nil,
		"foo/aidl_api/foo/2/IFoo.aidl": nil,
		"foo/aidl_api/foo/2/.hash":     nil,
	}))

	fooV1Java := FindModule(ctx, "foo-V1-java", "android_common", "foo").(*java.Library)
	android.AssertStringListContains(t, "a/foo-v1 deps", fooV1Java.CompilerDeps(), "common-V1-java")

	fooV2Java := FindModule(ctx, "foo-V2-java", "android_common", "foo").(*java.Library)
	android.AssertStringListContains(t, "a/foo-v2 deps", fooV2Java.CompilerDeps(), "common-V2-java")

	fooV3Java := FindModule(ctx, "foo-V3-java", "android_common", "foo").(*java.Library)
	android.AssertStringListContains(t, "a/foo-v3 deps", fooV3Java.CompilerDeps(), "common-V3-java")
}

func TestVersionsWithInfoImport(t *testing.T) {
	testAidlError(t, "imports in versions_with_info must specify its version", ``, withFiles(map[string][]byte{
		"common/Android.bp": []byte(`
		  aidl_interface {
				name: "common",
				srcs: ["ICommon.aidl"],
				versions: ["1", "2"],
			}
		`),
		"common/aidl_api/common/1/ICommon.aidl": nil,
		"common/aidl_api/common/1/.hash":        nil,
		"common/aidl_api/common/2/ICommon.aidl": nil,
		"common/aidl_api/common/2/.hash":        nil,
		"foo/Android.bp": []byte(`
			aidl_interface {
				name: "foo",
				srcs: ["IFoo.aidl"],
				imports: ["common"],
				versions_with_info: [
					{version: "1", imports: ["common"]},
					{version: "2", imports: ["common-V2"]},
				]
			}
		`),
		"foo/aidl_api/foo/1/IFoo.aidl": nil,
		"foo/aidl_api/foo/1/.hash":     nil,
		"foo/aidl_api/foo/2/IFoo.aidl": nil,
		"foo/aidl_api/foo/2/.hash":     nil,
	}))
}

func TestFreezeApiDeps(t *testing.T) {
	for _, transitive := range []bool{true, false} {
		for _, testcase := range []struct {
			string
			bool
		}{{"common", true}, {"common-V3", true}, {"common-V2", false}} {
			im := testcase.string
			customizers := []android.FixturePreparer{
				withFiles(map[string][]byte{
					"common/Android.bp": []byte(`
				  aidl_interface {
						name: "common",
						srcs: ["ICommon.aidl"],
						versions: ["1", "2"],
					}
				`),
					"common/aidl_api/common/1/ICommon.aidl": nil,
					"common/aidl_api/common/1/.hash":        nil,
					"common/aidl_api/common/2/ICommon.aidl": nil,
					"common/aidl_api/common/2/.hash":        nil,
					"foo/Android.bp": []byte(fmt.Sprintf(`
					aidl_interface {
						name: "foo",
						srcs: ["IFoo.aidl"],
						imports: ["%s"],
						versions_with_info: [
							{version: "1", imports: ["common-V1"]},
							{version: "2", imports: ["common-V2"]},
						]
					}
				`, im)),
					"foo/aidl_api/foo/1/IFoo.aidl": nil,
					"foo/aidl_api/foo/1/.hash":     nil,
					"foo/aidl_api/foo/2/IFoo.aidl": nil,
					"foo/aidl_api/foo/2/.hash":     nil,
				}),
			}
			if transitive {
				customizers = append(customizers, setTransitiveFreezeEnv())
			}

			ctx, _ := testAidl(t, ``, customizers...)
			shouldHaveDep := transitive && testcase.bool
			fooFreezeApiRule := ctx.ModuleForTests("foo-api", "").Output("updateapi_3.timestamp")
			commonFreezeApiOutput := ctx.ModuleForTests("common-api", "").Output("updateapi_3.timestamp").Output.String()
			testMethod := android.AssertStringListDoesNotContain
			if shouldHaveDep {
				testMethod = android.AssertStringListContains
			}
			testMethod(t, "Only if AIDL_TRANSITIVE_FREEZE is set and an aidl_interface depends on an another aidl_interface's ToT version, an imported aidl_interface should be frozen as well.",
				fooFreezeApiRule.Implicits.Strings(), commonFreezeApiOutput)
		}
	}
}
