// Copyright 2019 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 (
	"reflect"
	"runtime"
	"testing"

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

type Named struct {
	A *string `android:"arch_variant"`
	B *string
}

type NamedAllFiltered struct {
	A *string
}

type NamedNoneFiltered struct {
	A *string `android:"arch_variant"`
}

func TestFilterArchStruct(t *testing.T) {
	tests := []struct {
		name     string
		in       interface{}
		out      interface{}
		filtered bool
	}{
		// Property tests
		{
			name: "basic",
			in: &struct {
				A *string `android:"arch_variant"`
				B *string
			}{},
			out: &struct {
				A *string
			}{},
			filtered: true,
		},
		{
			name: "tags",
			in: &struct {
				A *string `android:"arch_variant"`
				B *string `android:"arch_variant,path"`
				C *string `android:"arch_variant,path,variant_prepend"`
				D *string `android:"path,variant_prepend,arch_variant"`
				E *string `android:"path"`
				F *string
			}{},
			out: &struct {
				A *string
				B *string `android:"path"`
				C *string `android:"path"`
				D *string `android:"path"`
			}{},
			filtered: true,
		},
		{
			name: "all filtered",
			in: &struct {
				A *string
			}{},
			out:      nil,
			filtered: true,
		},
		{
			name: "none filtered",
			in: &struct {
				A *string `android:"arch_variant"`
			}{},
			out: &struct {
				A *string `android:"arch_variant"`
			}{},
			filtered: false,
		},

		// Sub-struct tests
		{
			name: "substruct",
			in: &struct {
				A struct {
					A *string `android:"arch_variant"`
					B *string
				} `android:"arch_variant"`
			}{},
			out: &struct {
				A struct {
					A *string
				}
			}{},
			filtered: true,
		},
		{
			name: "substruct all filtered",
			in: &struct {
				A struct {
					A *string
				} `android:"arch_variant"`
			}{},
			out:      nil,
			filtered: true,
		},
		{
			name: "substruct none filtered",
			in: &struct {
				A struct {
					A *string `android:"arch_variant"`
				} `android:"arch_variant"`
			}{},
			out: &struct {
				A struct {
					A *string `android:"arch_variant"`
				} `android:"arch_variant"`
			}{},
			filtered: false,
		},

		// Named sub-struct tests
		{
			name: "named substruct",
			in: &struct {
				A Named `android:"arch_variant"`
			}{},
			out: &struct {
				A struct {
					A *string
				}
			}{},
			filtered: true,
		},
		{
			name: "substruct all filtered",
			in: &struct {
				A NamedAllFiltered `android:"arch_variant"`
			}{},
			out:      nil,
			filtered: true,
		},
		{
			name: "substruct none filtered",
			in: &struct {
				A NamedNoneFiltered `android:"arch_variant"`
			}{},
			out: &struct {
				A NamedNoneFiltered `android:"arch_variant"`
			}{},
			filtered: false,
		},

		// Pointer to sub-struct tests
		{
			name: "pointer substruct",
			in: &struct {
				A *struct {
					A *string `android:"arch_variant"`
					B *string
				} `android:"arch_variant"`
			}{},
			out: &struct {
				A *struct {
					A *string
				}
			}{},
			filtered: true,
		},
		{
			name: "pointer substruct all filtered",
			in: &struct {
				A *struct {
					A *string
				} `android:"arch_variant"`
			}{},
			out:      nil,
			filtered: true,
		},
		{
			name: "pointer substruct none filtered",
			in: &struct {
				A *struct {
					A *string `android:"arch_variant"`
				} `android:"arch_variant"`
			}{},
			out: &struct {
				A *struct {
					A *string `android:"arch_variant"`
				} `android:"arch_variant"`
			}{},
			filtered: false,
		},

		// Pointer to named sub-struct tests
		{
			name: "pointer named substruct",
			in: &struct {
				A *Named `android:"arch_variant"`
			}{},
			out: &struct {
				A *struct {
					A *string
				}
			}{},
			filtered: true,
		},
		{
			name: "pointer substruct all filtered",
			in: &struct {
				A *NamedAllFiltered `android:"arch_variant"`
			}{},
			out:      nil,
			filtered: true,
		},
		{
			name: "pointer substruct none filtered",
			in: &struct {
				A *NamedNoneFiltered `android:"arch_variant"`
			}{},
			out: &struct {
				A *NamedNoneFiltered `android:"arch_variant"`
			}{},
			filtered: false,
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			out, filtered := proptools.FilterPropertyStruct(reflect.TypeOf(test.in), filterArchStruct)
			if filtered != test.filtered {
				t.Errorf("expected filtered %v, got %v", test.filtered, filtered)
			}
			expected := reflect.TypeOf(test.out)
			if out != expected {
				t.Errorf("expected type %v, got %v", expected, out)
			}
		})
	}
}

type archTestModule struct {
	ModuleBase
	props struct {
		Deps []string
	}
}

func (m *archTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
}

func (m *archTestModule) DepsMutator(ctx BottomUpMutatorContext) {
	ctx.AddDependency(ctx.Module(), nil, m.props.Deps...)
}

func archTestModuleFactory() Module {
	m := &archTestModule{}
	m.AddProperties(&m.props)
	InitAndroidArchModule(m, HostAndDeviceSupported, MultilibBoth)
	return m
}

var prepareForArchTest = GroupFixturePreparers(
	PrepareForTestWithArchMutator,
	FixtureRegisterWithContext(func(ctx RegistrationContext) {
		ctx.RegisterModuleType("module", archTestModuleFactory)
	}),
)

func TestArchMutator(t *testing.T) {
	var buildOSVariants []string
	var buildOS32Variants []string
	switch runtime.GOOS {
	case "linux":
		buildOSVariants = []string{"linux_glibc_x86_64", "linux_glibc_x86"}
		buildOS32Variants = []string{"linux_glibc_x86"}
	case "darwin":
		buildOSVariants = []string{"darwin_x86_64"}
		buildOS32Variants = nil
	}

	bp := `
		module {
			name: "foo",
		}

		module {
			name: "bar",
			host_supported: true,
		}

		module {
			name: "baz",
			device_supported: false,
		}

		module {
			name: "qux",
			host_supported: true,
			compile_multilib: "32",
		}
	`

	testCases := []struct {
		name        string
		preparer    FixturePreparer
		fooVariants []string
		barVariants []string
		bazVariants []string
		quxVariants []string
	}{
		{
			name:        "normal",
			preparer:    nil,
			fooVariants: []string{"android_arm64_armv8-a", "android_arm_armv7-a-neon"},
			barVariants: append(buildOSVariants, "android_arm64_armv8-a", "android_arm_armv7-a-neon"),
			bazVariants: nil,
			quxVariants: append(buildOS32Variants, "android_arm_armv7-a-neon"),
		},
		{
			name: "host-only",
			preparer: FixtureModifyConfig(func(config Config) {
				config.BuildOSTarget = Target{}
				config.BuildOSCommonTarget = Target{}
				config.Targets[Android] = nil
			}),
			fooVariants: nil,
			barVariants: buildOSVariants,
			bazVariants: nil,
			quxVariants: buildOS32Variants,
		},
	}

	enabledVariants := func(ctx *TestContext, name string) []string {
		var ret []string
		variants := ctx.ModuleVariantsForTests(name)
		for _, variant := range variants {
			m := ctx.ModuleForTests(name, variant)
			if m.Module().Enabled() {
				ret = append(ret, variant)
			}
		}
		return ret
	}

	for _, tt := range testCases {
		t.Run(tt.name, func(t *testing.T) {
			result := GroupFixturePreparers(
				prepareForArchTest,
				// Test specific preparer
				OptionalFixturePreparer(tt.preparer),
				FixtureWithRootAndroidBp(bp),
			).RunTest(t)
			ctx := result.TestContext

			if g, w := enabledVariants(ctx, "foo"), tt.fooVariants; !reflect.DeepEqual(w, g) {
				t.Errorf("want foo variants:\n%q\ngot:\n%q\n", w, g)
			}

			if g, w := enabledVariants(ctx, "bar"), tt.barVariants; !reflect.DeepEqual(w, g) {
				t.Errorf("want bar variants:\n%q\ngot:\n%q\n", w, g)
			}

			if g, w := enabledVariants(ctx, "baz"), tt.bazVariants; !reflect.DeepEqual(w, g) {
				t.Errorf("want baz variants:\n%q\ngot:\n%q\n", w, g)
			}

			if g, w := enabledVariants(ctx, "qux"), tt.quxVariants; !reflect.DeepEqual(w, g) {
				t.Errorf("want qux variants:\n%q\ngot:\n%q\n", w, g)
			}
		})
	}
}

func TestArchMutatorNativeBridge(t *testing.T) {
	bp := `
		// This module is only enabled for x86.
		module {
			name: "foo",
		}

		// This module is enabled for x86 and arm (via native bridge).
		module {
			name: "bar",
			native_bridge_supported: true,
		}

		// This module is enabled for arm (native_bridge) only.
		module {
			name: "baz",
			native_bridge_supported: true,
			enabled: false,
			target: {
				native_bridge: {
					enabled: true,
				}
			}
		}
	`

	testCases := []struct {
		name        string
		preparer    FixturePreparer
		fooVariants []string
		barVariants []string
		bazVariants []string
	}{
		{
			name:        "normal",
			preparer:    nil,
			fooVariants: []string{"android_x86_64_silvermont", "android_x86_silvermont"},
			barVariants: []string{"android_x86_64_silvermont", "android_native_bridge_arm64_armv8-a", "android_x86_silvermont", "android_native_bridge_arm_armv7-a-neon"},
			bazVariants: []string{"android_native_bridge_arm64_armv8-a", "android_native_bridge_arm_armv7-a-neon"},
		},
	}

	enabledVariants := func(ctx *TestContext, name string) []string {
		var ret []string
		variants := ctx.ModuleVariantsForTests(name)
		for _, variant := range variants {
			m := ctx.ModuleForTests(name, variant)
			if m.Module().Enabled() {
				ret = append(ret, variant)
			}
		}
		return ret
	}

	for _, tt := range testCases {
		t.Run(tt.name, func(t *testing.T) {
			result := GroupFixturePreparers(
				prepareForArchTest,
				// Test specific preparer
				OptionalFixturePreparer(tt.preparer),
				// Prepare for native bridge test
				FixtureModifyConfig(func(config Config) {
					config.Targets[Android] = []Target{
						{Android, Arch{ArchType: X86_64, ArchVariant: "silvermont", Abi: []string{"arm64-v8a"}}, NativeBridgeDisabled, "", "", false},
						{Android, Arch{ArchType: X86, ArchVariant: "silvermont", Abi: []string{"armeabi-v7a"}}, NativeBridgeDisabled, "", "", false},
						{Android, Arch{ArchType: Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}, NativeBridgeEnabled, "x86_64", "arm64", false},
						{Android, Arch{ArchType: Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}, NativeBridgeEnabled, "x86", "arm", false},
					}
				}),
				FixtureWithRootAndroidBp(bp),
			).RunTest(t)

			ctx := result.TestContext

			if g, w := enabledVariants(ctx, "foo"), tt.fooVariants; !reflect.DeepEqual(w, g) {
				t.Errorf("want foo variants:\n%q\ngot:\n%q\n", w, g)
			}

			if g, w := enabledVariants(ctx, "bar"), tt.barVariants; !reflect.DeepEqual(w, g) {
				t.Errorf("want bar variants:\n%q\ngot:\n%q\n", w, g)
			}

			if g, w := enabledVariants(ctx, "baz"), tt.bazVariants; !reflect.DeepEqual(w, g) {
				t.Errorf("want qux variants:\n%q\ngot:\n%q\n", w, g)
			}
		})
	}
}
