// Copyright 2017 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 python

import (
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"reflect"
	"sort"
	"strings"
	"testing"

	"android/soong/android"
)

type pyModule struct {
	name           string
	actualVersion  string
	pyRunfiles     []string
	depsPyRunfiles []string
	parSpec        string
	depsParSpecs   []string
}

var (
	buildNamePrefix          = "soong_python_test"
	moduleVariantErrTemplate = "%s: module %q variant %q: "
	pkgPathErrTemplate       = moduleVariantErrTemplate +
		"pkg_path: %q must be a relative path contained in par file."
	badIdentifierErrTemplate = moduleVariantErrTemplate +
		"srcs: the path %q contains invalid token %q."
	dupRunfileErrTemplate = moduleVariantErrTemplate +
		"found two files to be placed at the same runfiles location %q." +
		" First file: in module %s at path %q." +
		" Second file: in module %s at path %q."
	noSrcFileErr      = moduleVariantErrTemplate + "doesn't have any source files!"
	badSrcFileExtErr  = moduleVariantErrTemplate + "srcs: found non (.py) file: %q!"
	badDataFileExtErr = moduleVariantErrTemplate + "data: found (.py) file: %q!"
	bpFile            = "Blueprints"

	data = []struct {
		desc      string
		mockFiles map[string][]byte

		errors           []string
		expectedBinaries []pyModule
	}{
		{
			desc: "module without any src files",
			mockFiles: map[string][]byte{
				bpFile: []byte(`subdirs = ["dir"]`),
				filepath.Join("dir", bpFile): []byte(
					`python_library_host {
						name: "lib1",
					}`,
				),
			},
			errors: []string{
				fmt.Sprintf(noSrcFileErr,
					"dir/Blueprints:1:1", "lib1", "PY3"),
			},
		},
		{
			desc: "module with bad src file ext",
			mockFiles: map[string][]byte{
				bpFile: []byte(`subdirs = ["dir"]`),
				filepath.Join("dir", bpFile): []byte(
					`python_library_host {
						name: "lib1",
						srcs: [
							"file1.exe",
						],
					}`,
				),
				"dir/file1.exe": nil,
			},
			errors: []string{
				fmt.Sprintf(badSrcFileExtErr,
					"dir/Blueprints:3:11", "lib1", "PY3", "dir/file1.exe"),
			},
		},
		{
			desc: "module with bad data file ext",
			mockFiles: map[string][]byte{
				bpFile: []byte(`subdirs = ["dir"]`),
				filepath.Join("dir", bpFile): []byte(
					`python_library_host {
						name: "lib1",
						srcs: [
							"file1.py",
						],
						data: [
							"file2.py",
						],
					}`,
				),
				"dir/file1.py": nil,
				"dir/file2.py": nil,
			},
			errors: []string{
				fmt.Sprintf(badDataFileExtErr,
					"dir/Blueprints:6:11", "lib1", "PY3", "dir/file2.py"),
			},
		},
		{
			desc: "module with bad pkg_path format",
			mockFiles: map[string][]byte{
				bpFile: []byte(`subdirs = ["dir"]`),
				filepath.Join("dir", bpFile): []byte(
					`python_library_host {
						name: "lib1",
						pkg_path: "a/c/../../",
						srcs: [
							"file1.py",
						],
					}

					python_library_host {
						name: "lib2",
						pkg_path: "a/c/../../../",
						srcs: [
							"file1.py",
						],
					}

					python_library_host {
						name: "lib3",
						pkg_path: "/a/c/../../",
						srcs: [
							"file1.py",
						],
					}`,
				),
				"dir/file1.py": nil,
			},
			errors: []string{
				fmt.Sprintf(pkgPathErrTemplate,
					"dir/Blueprints:11:15", "lib2", "PY3", "a/c/../../../"),
				fmt.Sprintf(pkgPathErrTemplate,
					"dir/Blueprints:19:15", "lib3", "PY3", "/a/c/../../"),
			},
		},
		{
			desc: "module with bad runfile src path format",
			mockFiles: map[string][]byte{
				bpFile: []byte(`subdirs = ["dir"]`),
				filepath.Join("dir", bpFile): []byte(
					`python_library_host {
						name: "lib1",
						pkg_path: "a/b/c/",
						srcs: [
							".file1.py",
							"123/file1.py",
							"-e/f/file1.py",
						],
					}`,
				),
				"dir/.file1.py":     nil,
				"dir/123/file1.py":  nil,
				"dir/-e/f/file1.py": nil,
			},
			errors: []string{
				fmt.Sprintf(badIdentifierErrTemplate, "dir/Blueprints:4:11",
					"lib1", "PY3", "runfiles/a/b/c/-e/f/file1.py", "-e"),
				fmt.Sprintf(badIdentifierErrTemplate, "dir/Blueprints:4:11",
					"lib1", "PY3", "runfiles/a/b/c/.file1.py", ".file1"),
				fmt.Sprintf(badIdentifierErrTemplate, "dir/Blueprints:4:11",
					"lib1", "PY3", "runfiles/a/b/c/123/file1.py", "123"),
			},
		},
		{
			desc: "module with duplicate runfile path",
			mockFiles: map[string][]byte{
				bpFile: []byte(`subdirs = ["dir"]`),
				filepath.Join("dir", bpFile): []byte(
					`python_library_host {
						name: "lib1",
						pkg_path: "a/b/",
						srcs: [
							"c/file1.py",
						],
					}

					python_library_host {
						name: "lib2",
						pkg_path: "a/b/c/",
						srcs: [
							"file1.py",
						],
						libs: [
							"lib1",
						],
					}
					`,
				),
				"dir/c/file1.py": nil,
				"dir/file1.py":   nil,
			},
			errors: []string{
				fmt.Sprintf(dupRunfileErrTemplate, "dir/Blueprints:9:6",
					"lib2", "PY3", "runfiles/a/b/c/file1.py", "lib2", "dir/file1.py",
					"lib1", "dir/c/file1.py"),
			},
		},
		{
			desc: "module for testing dependencies",
			mockFiles: map[string][]byte{
				bpFile: []byte(`subdirs = ["dir"]`),
				filepath.Join("dir", bpFile): []byte(
					`python_defaults {
						name: "default_lib",
						srcs: [
							"default.py",
						],
						version: {
							py2: {
								enabled: true,
								srcs: [
									"default_py2.py",
								],
							},
							py3: {
								enabled: false,
								srcs: [
									"default_py3.py",
								],
							},
						},
					}

					python_library_host {
						name: "lib5",
						pkg_path: "a/b/",
						srcs: [
							"file1.py",
						],
						version: {
							py2: {
								enabled: true,
							},
							py3: {
								enabled: true,
							},
						},
					}

					python_library_host {
						name: "lib6",
						pkg_path: "c/d/",
						srcs: [
							"file2.py",
						],
						libs: [
							"lib5",
						],
					}

					python_binary_host {
						name: "bin",
						defaults: ["default_lib"],
						pkg_path: "e/",
						srcs: [
							"bin.py",
						],
						libs: [
							"lib5",
						],
						version: {
							py3: {
								enabled: true,
								srcs: [
									"file4.py",
								],
								libs: [
									"lib6",
								],
							},
						},
					}`,
				),
				filepath.Join("dir", "default.py"):     nil,
				filepath.Join("dir", "default_py2.py"): nil,
				filepath.Join("dir", "default_py3.py"): nil,
				filepath.Join("dir", "file1.py"):       nil,
				filepath.Join("dir", "file2.py"):       nil,
				filepath.Join("dir", "bin.py"):         nil,
				filepath.Join("dir", "file4.py"):       nil,
				stubTemplateHost: []byte(`PYTHON_BINARY = '%interpreter%'
				MAIN_FILE = '%main%'`),
			},
			expectedBinaries: []pyModule{
				{
					name:          "bin",
					actualVersion: "PY3",
					pyRunfiles: []string{
						"runfiles/e/default.py",
						"runfiles/e/bin.py",
						"runfiles/e/default_py3.py",
						"runfiles/e/file4.py",
					},
					depsPyRunfiles: []string{
						"runfiles/a/b/file1.py",
						"runfiles/c/d/file2.py",
					},
					parSpec: "-P runfiles/e -C dir/ -l @prefix@/.intermediates/dir/bin/PY3/dir_.list",
					depsParSpecs: []string{
						"-P runfiles/a/b -C dir/ -l @prefix@/.intermediates/dir/lib5/PY3/dir_.list",
						"-P runfiles/c/d -C dir/ -l @prefix@/.intermediates/dir/lib6/PY3/dir_.list",
					},
				},
			},
		},
	}
)

func TestPythonModule(t *testing.T) {
	config, buildDir := setupBuildEnv(t)
	defer tearDownBuildEnv(buildDir)
	for _, d := range data {
		t.Run(d.desc, func(t *testing.T) {
			ctx := android.NewTestContext()
			ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
				ctx.BottomUp("version_split", versionSplitMutator()).Parallel()
			})
			ctx.RegisterModuleType("python_library_host",
				android.ModuleFactoryAdaptor(PythonLibraryHostFactory))
			ctx.RegisterModuleType("python_binary_host",
				android.ModuleFactoryAdaptor(PythonBinaryHostFactory))
			ctx.RegisterModuleType("python_defaults",
				android.ModuleFactoryAdaptor(defaultsFactory))
			ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
			ctx.Register()
			ctx.MockFileSystem(d.mockFiles)
			_, testErrs := ctx.ParseBlueprintsFiles(bpFile)
			fail(t, testErrs)
			_, actErrs := ctx.PrepareBuildActions(config)
			if len(actErrs) > 0 {
				testErrs = append(testErrs, expectErrors(t, actErrs, d.errors)...)
			} else {
				for _, e := range d.expectedBinaries {
					testErrs = append(testErrs,
						expectModule(t, ctx, buildDir, e.name,
							e.actualVersion,
							e.pyRunfiles, e.depsPyRunfiles,
							e.parSpec, e.depsParSpecs)...)
				}
			}
			fail(t, testErrs)
		})
	}
}

func expectErrors(t *testing.T, actErrs []error, expErrs []string) (testErrs []error) {
	actErrStrs := []string{}
	for _, v := range actErrs {
		actErrStrs = append(actErrStrs, v.Error())
	}
	sort.Strings(actErrStrs)
	if len(actErrStrs) != len(expErrs) {
		t.Errorf("got (%d) errors, expected (%d) errors!", len(actErrStrs), len(expErrs))
		for _, v := range actErrStrs {
			testErrs = append(testErrs, errors.New(v))
		}
	} else {
		sort.Strings(expErrs)
		for i, v := range actErrStrs {
			if v != expErrs[i] {
				testErrs = append(testErrs, errors.New(v))
			}
		}
	}

	return
}

func expectModule(t *testing.T, ctx *android.TestContext, buildDir, name, variant string,
	expPyRunfiles, expDepsPyRunfiles []string,
	expParSpec string, expDepsParSpecs []string) (testErrs []error) {
	module := ctx.ModuleForTests(name, variant)

	base, baseOk := module.Module().(*Module)
	if !baseOk {
		t.Fatalf("%s is not Python module!", name)
	}

	actPyRunfiles := []string{}
	for _, path := range base.srcsPathMappings {
		actPyRunfiles = append(actPyRunfiles, path.dest)
	}

	if !reflect.DeepEqual(actPyRunfiles, expPyRunfiles) {
		testErrs = append(testErrs, errors.New(fmt.Sprintf(
			`binary "%s" variant "%s" has unexpected pyRunfiles: %q!`,
			base.Name(),
			base.properties.Actual_version,
			actPyRunfiles)))
	}

	if !reflect.DeepEqual(base.depsPyRunfiles, expDepsPyRunfiles) {
		testErrs = append(testErrs, errors.New(fmt.Sprintf(
			`binary "%s" variant "%s" has unexpected depsPyRunfiles: %q!`,
			base.Name(),
			base.properties.Actual_version,
			base.depsPyRunfiles)))
	}

	if base.parSpec.soongParArgs() != strings.Replace(expParSpec, "@prefix@", buildDir, 1) {
		testErrs = append(testErrs, errors.New(fmt.Sprintf(
			`binary "%s" variant "%s" has unexpected parSpec: %q!`,
			base.Name(),
			base.properties.Actual_version,
			base.parSpec.soongParArgs())))
	}

	actDepsParSpecs := []string{}
	for i, p := range base.depsParSpecs {
		actDepsParSpecs = append(actDepsParSpecs, p.soongParArgs())
		expDepsParSpecs[i] = strings.Replace(expDepsParSpecs[i], "@prefix@", buildDir, 1)
	}

	if !reflect.DeepEqual(actDepsParSpecs, expDepsParSpecs) {
		testErrs = append(testErrs, errors.New(fmt.Sprintf(
			`binary "%s" variant "%s" has unexpected depsParSpecs: %q!`,
			base.Name(),
			base.properties.Actual_version,
			actDepsParSpecs)))
	}

	return
}

func setupBuildEnv(t *testing.T) (config android.Config, buildDir string) {
	buildDir, err := ioutil.TempDir("", buildNamePrefix)
	if err != nil {
		t.Fatal(err)
	}

	config = android.TestConfig(buildDir, nil)

	return
}

func tearDownBuildEnv(buildDir string) {
	os.RemoveAll(buildDir)
}

func fail(t *testing.T, errs []error) {
	if len(errs) > 0 {
		for _, err := range errs {
			t.Error(err)
		}
		t.FailNow()
	}
}
