// Copyright 2018 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 android

import (
	"testing"
)

var neverallowTests = []struct {
	name          string
	fs            map[string][]byte
	expectedError string
}{
	// include_dir rule tests
	{
		name: "include_dir not allowed to reference art",
		fs: map[string][]byte{
			"other/Blueprints": []byte(`
				cc_library {
					name: "libother",
					include_dirs: ["art/libdexfile/include"],
				}`),
		},
		expectedError: "all usages of 'art' have been migrated",
	},
	{
		name: "include_dir can reference another location",
		fs: map[string][]byte{
			"other/Blueprints": []byte(`
				cc_library {
					name: "libother",
					include_dirs: ["another/include"],
				}`),
		},
	},
	// Treble rule tests
	{
		name: "no vndk.enabled under vendor directory",
		fs: map[string][]byte{
			"vendor/Blueprints": []byte(`
				cc_library {
					name: "libvndk",
					vendor_available: true,
					vndk: {
						enabled: true,
					},
				}`),
		},
		expectedError: "VNDK can never contain a library that is device dependent",
	},
	{
		name: "no vndk.enabled under device directory",
		fs: map[string][]byte{
			"device/Blueprints": []byte(`
				cc_library {
					name: "libvndk",
					vendor_available: true,
					vndk: {
						enabled: true,
					},
				}`),
		},
		expectedError: "VNDK can never contain a library that is device dependent",
	},
	{
		name: "vndk-ext under vendor or device directory",
		fs: map[string][]byte{
			"device/Blueprints": []byte(`
				cc_library {
					name: "libvndk1_ext",
					vendor: true,
					vndk: {
						enabled: true,
					},
				}`),
			"vendor/Blueprints": []byte(`
				cc_library {
					name: "libvndk2_ext",
					vendor: true,
					vndk: {
						enabled: true,
					},
				}`),
		},
		expectedError: "",
	},

	{
		name: "no enforce_vintf_manifest.cflags",
		fs: map[string][]byte{
			"Blueprints": []byte(`
				cc_library {
					name: "libexample",
					product_variables: {
						enforce_vintf_manifest: {
							cflags: ["-DSHOULD_NOT_EXIST"],
						},
					},
				}`),
		},
		expectedError: "manifest enforcement should be independent",
	},
	{
		name: "libhidltransport enforce_vintf_manifest.cflags",
		fs: map[string][]byte{
			"Blueprints": []byte(`
				cc_library {
					name: "libhidltransport",
					product_variables: {
						enforce_vintf_manifest: {
							cflags: ["-DSHOULD_NOT_EXIST"],
						},
					},
				}`),
		},
		expectedError: "",
	},

	{
		name: "no treble_linker_namespaces.cflags",
		fs: map[string][]byte{
			"Blueprints": []byte(`
				cc_library {
					name: "libexample",
					product_variables: {
						treble_linker_namespaces: {
							cflags: ["-DSHOULD_NOT_EXIST"],
						},
					},
				}`),
		},
		expectedError: "nothing should care if linker namespaces are enabled or not",
	},
	{
		name: "libc_bionic_ndk treble_linker_namespaces.cflags",
		fs: map[string][]byte{
			"Blueprints": []byte(`
				cc_library {
					name: "libc_bionic_ndk",
					product_variables: {
						treble_linker_namespaces: {
							cflags: ["-DSHOULD_NOT_EXIST"],
						},
					},
				}`),
		},
		expectedError: "",
	},
	{
		name: "java_device_for_host",
		fs: map[string][]byte{
			"Blueprints": []byte(`
				java_device_for_host {
					name: "device_for_host",
					libs: ["core-libart"],
				}`),
		},
		expectedError: "java_device_for_host can only be used in whitelisted projects",
	},
	// Libcore rule tests
	{
		name: "sdk_version: \"none\" inside core libraries",
		fs: map[string][]byte{
			"libcore/Blueprints": []byte(`
				java_library {
					name: "inside_core_libraries",
					sdk_version: "none",
				}`),
		},
	},
	{
		name: "sdk_version: \"none\" outside core libraries",
		fs: map[string][]byte{
			"Blueprints": []byte(`
				java_library {
					name: "outside_core_libraries",
					sdk_version: "none",
				}`),
		},
		expectedError: "module \"outside_core_libraries\": violates neverallow",
	},
	{
		name: "sdk_version: \"current\"",
		fs: map[string][]byte{
			"Blueprints": []byte(`
				java_library {
					name: "outside_core_libraries",
					sdk_version: "current",
				}`),
		},
	},
}

func TestNeverallow(t *testing.T) {
	config := TestConfig(buildDir, nil)

	for _, test := range neverallowTests {
		t.Run(test.name, func(t *testing.T) {
			_, errs := testNeverallow(t, config, test.fs)

			if test.expectedError == "" {
				FailIfErrored(t, errs)
			} else {
				FailIfNoMatchingErrors(t, test.expectedError, errs)
			}
		})
	}
}

func testNeverallow(t *testing.T, config Config, fs map[string][]byte) (*TestContext, []error) {
	ctx := NewTestContext()
	ctx.RegisterModuleType("cc_library", ModuleFactoryAdaptor(newMockCcLibraryModule))
	ctx.RegisterModuleType("java_library", ModuleFactoryAdaptor(newMockJavaLibraryModule))
	ctx.RegisterModuleType("java_library_host", ModuleFactoryAdaptor(newMockJavaLibraryModule))
	ctx.RegisterModuleType("java_device_for_host", ModuleFactoryAdaptor(newMockJavaLibraryModule))
	ctx.PostDepsMutators(registerNeverallowMutator)
	ctx.Register()

	ctx.MockFileSystem(fs)

	_, errs := ctx.ParseBlueprintsFiles("Blueprints")
	if len(errs) > 0 {
		return ctx, errs
	}

	_, errs = ctx.PrepareBuildActions(config)
	return ctx, errs
}

type mockCcLibraryProperties struct {
	Include_dirs     []string
	Vendor_available *bool

	Vndk struct {
		Enabled                *bool
		Support_system_process *bool
		Extends                *string
	}

	Product_variables struct {
		Enforce_vintf_manifest struct {
			Cflags []string
		}

		Treble_linker_namespaces struct {
			Cflags []string
		}
	}
}

type mockCcLibraryModule struct {
	ModuleBase
	properties mockCcLibraryProperties
}

func newMockCcLibraryModule() Module {
	m := &mockCcLibraryModule{}
	m.AddProperties(&m.properties)
	InitAndroidModule(m)
	return m
}

func (p *mockCcLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
}

type mockJavaLibraryProperties struct {
	Libs        []string
	Sdk_version *string
}

type mockJavaLibraryModule struct {
	ModuleBase
	properties mockJavaLibraryProperties
}

func newMockJavaLibraryModule() Module {
	m := &mockJavaLibraryModule{}
	m.AddProperties(&m.properties)
	InitAndroidModule(m)
	return m
}

func (p *mockJavaLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
}
