// Copyright 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 rust

import (
	"strings"
	"testing"

	"android/soong/android"
	"android/soong/cc"
)

// Test that feature flags are being correctly generated.
func TestFeaturesToFlags(t *testing.T) {
	ctx := testRust(t, `
		rust_library_host_dylib {
			name: "libfoo",
			srcs: ["foo.rs"],
			crate_name: "foo",
			features: [
				"fizz",
				"buzz"
			],
		}`)

	libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")

	if !strings.Contains(libfooDylib.Args["rustcFlags"], "cfg 'feature=\"fizz\"'") ||
		!strings.Contains(libfooDylib.Args["rustcFlags"], "cfg 'feature=\"buzz\"'") {
		t.Fatalf("missing fizz and buzz feature flags for libfoo dylib, rustcFlags: %#v", libfooDylib.Args["rustcFlags"])
	}
}

// Test that we reject multiple source files.
func TestEnforceSingleSourceFile(t *testing.T) {

	singleSrcError := "srcs can only contain one path for a rust file and source providers prefixed by \":\""

	// Test libraries
	testRustError(t, singleSrcError, `
		rust_library_host {
			name: "foo-bar-library",
			srcs: ["foo.rs", "src/bar.rs"],
		}`)

	// Test binaries
	testRustError(t, singleSrcError, `
			rust_binary_host {
				name: "foo-bar-binary",
				srcs: ["foo.rs", "src/bar.rs"],
			}`)

	// Test proc_macros
	testRustError(t, singleSrcError, `
		rust_proc_macro {
			name: "foo-bar-proc-macro",
			srcs: ["foo.rs", "src/bar.rs"],
		}`)

	// Test prebuilts
	testRustError(t, singleSrcError, `
		rust_prebuilt_dylib {
			name: "foo-bar-prebuilt",
			srcs: ["liby.so", "libz.so"],
		  host_supported: true,
		}`)
}

func TestInstallDir(t *testing.T) {
	ctx := testRust(t, `
		rust_library_dylib {
			name: "libfoo",
			srcs: ["foo.rs"],
			crate_name: "foo",
		}
		rust_binary {
			name: "fizzbuzz",
			srcs: ["foo.rs"],
		}`)

	install_path_lib64 := ctx.ModuleForTests("libfoo",
		"android_arm64_armv8-a_dylib").Module().(*Module).compiler.(*libraryDecorator).path.String()
	install_path_lib32 := ctx.ModuleForTests("libfoo",
		"android_arm_armv7-a-neon_dylib").Module().(*Module).compiler.(*libraryDecorator).path.String()
	install_path_bin := ctx.ModuleForTests("fizzbuzz",
		"android_arm64_armv8-a").Module().(*Module).compiler.(*binaryDecorator).path.String()

	if !strings.HasSuffix(install_path_lib64, "system/lib64/libfoo.dylib.so") {
		t.Fatalf("unexpected install path for 64-bit library: %#v", install_path_lib64)
	}
	if !strings.HasSuffix(install_path_lib32, "system/lib/libfoo.dylib.so") {
		t.Fatalf("unexpected install path for 32-bit library: %#v", install_path_lib32)
	}
	if !strings.HasSuffix(install_path_bin, "system/bin/fizzbuzz") {
		t.Fatalf("unexpected install path for binary: %#v", install_path_bin)
	}
}

func TestLints(t *testing.T) {

	bp := `
		// foo uses the default value of lints
		rust_library {
			name: "libfoo",
			srcs: ["foo.rs"],
			crate_name: "foo",
		}
		// bar forces the use of the "android" lint set
		rust_library {
			name: "libbar",
			srcs: ["foo.rs"],
			crate_name: "bar",
			lints: "android",
		}
		// foobar explicitly disable all lints
		rust_library {
			name: "libfoobar",
			srcs: ["foo.rs"],
			crate_name: "foobar",
			lints: "none",
		}`

	bp = bp + GatherRequiredDepsForTest()
	bp = bp + cc.GatherRequiredDepsForTest(android.NoOsType)

	fs := map[string][]byte{
		// Reuse the same blueprint file for subdirectories.
		"external/Android.bp": []byte(bp),
		"hardware/Android.bp": []byte(bp),
	}

	var lintTests = []struct {
		modulePath string
		fooFlags   string
	}{
		{"", "${config.RustDefaultLints}"},
		{"external/", "${config.RustAllowAllLints}"},
		{"hardware/", "${config.RustVendorLints}"},
	}

	for _, tc := range lintTests {
		t.Run("path="+tc.modulePath, func(t *testing.T) {

			config := android.TestArchConfig(buildDir, nil, bp, fs)
			ctx := CreateTestContext(config)
			ctx.Register()
			_, errs := ctx.ParseFileList(".", []string{tc.modulePath + "Android.bp"})
			android.FailIfErrored(t, errs)
			_, errs = ctx.PrepareBuildActions(config)
			android.FailIfErrored(t, errs)

			r := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib").MaybeRule("rustc")
			if !strings.Contains(r.Args["rustcFlags"], tc.fooFlags) {
				t.Errorf("Incorrect flags for libfoo: %q, want %q", r.Args["rustcFlags"], tc.fooFlags)
			}

			r = ctx.ModuleForTests("libbar", "android_arm64_armv8-a_dylib").MaybeRule("rustc")
			if !strings.Contains(r.Args["rustcFlags"], "${config.RustDefaultLints}") {
				t.Errorf("Incorrect flags for libbar: %q, want %q", r.Args["rustcFlags"], "${config.RustDefaultLints}")
			}

			r = ctx.ModuleForTests("libfoobar", "android_arm64_armv8-a_dylib").MaybeRule("rustc")
			if !strings.Contains(r.Args["rustcFlags"], "${config.RustAllowAllLints}") {
				t.Errorf("Incorrect flags for libfoobar: %q, want %q", r.Args["rustcFlags"], "${config.RustAllowAllLints}")
			}

		})
	}
}

// Test that devices are linking the stdlib dynamically
func TestStdDeviceLinkage(t *testing.T) {
	ctx := testRust(t, `
		rust_binary {
			name: "fizz",
			srcs: ["foo.rs"],
		}
		rust_library {
			name: "libfoo",
			srcs: ["foo.rs"],
			crate_name: "foo",
		}`)
	fizz := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Module().(*Module)
	fooRlib := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_rlib_dylib-std").Module().(*Module)
	fooDylib := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib").Module().(*Module)

	if !android.InList("libstd", fizz.Properties.AndroidMkDylibs) {
		t.Errorf("libstd is not linked dynamically for device binaries")
	}
	if !android.InList("libstd", fooRlib.Properties.AndroidMkDylibs) {
		t.Errorf("libstd is not linked dynamically for rlibs")
	}
	if !android.InList("libstd", fooDylib.Properties.AndroidMkDylibs) {
		t.Errorf("libstd is not linked dynamically for dylibs")
	}
}
