// 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 microfactory

import (
	"flag"
	"io/ioutil"
	"os"
	"path/filepath"
	"reflect"
	"runtime"
	"testing"
	"time"
)

func TestSimplePackagePathMap(t *testing.T) {
	t.Parallel()

	pkgMap := pkgPathMappingVar{&Config{}}
	flags := flag.NewFlagSet("", flag.ContinueOnError)
	flags.Var(&pkgMap, "m", "")
	err := flags.Parse([]string{
		"-m", "android/soong=build/soong/",
		"-m", "github.com/google/blueprint/=build/blueprint",
	})
	if err != nil {
		t.Fatal(err)
	}

	compare := func(got, want interface{}) {
		if !reflect.DeepEqual(got, want) {
			t.Errorf("Unexpected values in .pkgs:\nwant: %v\n got: %v",
				want, got)
		}
	}

	wantPkgs := []string{"android/soong", "github.com/google/blueprint"}
	compare(pkgMap.pkgs, wantPkgs)
	compare(pkgMap.paths[wantPkgs[0]], "build/soong")
	compare(pkgMap.paths[wantPkgs[1]], "build/blueprint")

	got, ok, err := pkgMap.Path("android/soong/ui/test")
	if err != nil {
		t.Error("Unexpected error in pkgMap.Path(soong):", err)
	} else if !ok {
		t.Error("Expected a result from pkgMap.Path(soong)")
	} else {
		compare(got, "build/soong/ui/test")
	}

	got, ok, err = pkgMap.Path("github.com/google/blueprint")
	if err != nil {
		t.Error("Unexpected error in pkgMap.Path(blueprint):", err)
	} else if !ok {
		t.Error("Expected a result from pkgMap.Path(blueprint)")
	} else {
		compare(got, "build/blueprint")
	}
}

func TestBadPackagePathMap(t *testing.T) {
	t.Parallel()

	pkgMap := pkgPathMappingVar{&Config{}}
	if _, _, err := pkgMap.Path("testing"); err == nil {
		t.Error("Expected error if no maps are specified")
	}
	if err := pkgMap.Set(""); err == nil {
		t.Error("Expected error with blank argument, but none returned")
	}
	if err := pkgMap.Set("a=a"); err != nil {
		t.Errorf("Unexpected error: %v", err)
	}
	if err := pkgMap.Set("a=b"); err == nil {
		t.Error("Expected error with duplicate package prefix, but none returned")
	}
	if _, ok, err := pkgMap.Path("testing"); err != nil {
		t.Errorf("Unexpected error: %v", err)
	} else if ok {
		t.Error("Expected testing to be consider in the stdlib")
	}
}

// TestSingleBuild ensures that just a basic build works.
func TestSingleBuild(t *testing.T) {
	t.Parallel()

	setupDir(t, func(config *Config, dir string, loadPkg loadPkgFunc) {
		// The output binary
		out := filepath.Join(dir, "out", "test")

		pkg := loadPkg()

		if err := pkg.Compile(config, filepath.Join(dir, "out")); err != nil {
			t.Fatal("Got error when compiling:", err)
		}

		if err := pkg.Link(config, out); err != nil {
			t.Fatal("Got error when linking:", err)
		}

		if _, err := os.Stat(out); err != nil {
			t.Error("Cannot stat output:", err)
		}
	})
}

// testBuildAgain triggers two builds, running the modify function in between
// each build. It verifies that the second build did or did not actually need
// to rebuild anything based on the shouldRebuild argument.
func testBuildAgain(t *testing.T,
	shouldRecompile, shouldRelink bool,
	modify func(config *Config, dir string, loadPkg loadPkgFunc),
	after func(pkg *GoPackage)) {

	t.Parallel()

	setupDir(t, func(config *Config, dir string, loadPkg loadPkgFunc) {
		// The output binary
		out := filepath.Join(dir, "out", "test")

		pkg := loadPkg()

		if err := pkg.Compile(config, filepath.Join(dir, "out")); err != nil {
			t.Fatal("Got error when compiling:", err)
		}

		if err := pkg.Link(config, out); err != nil {
			t.Fatal("Got error when linking:", err)
		}

		var firstTime time.Time
		if stat, err := os.Stat(out); err == nil {
			firstTime = stat.ModTime()
		} else {
			t.Fatal("Failed to stat output file:", err)
		}

		// mtime on HFS+ (the filesystem on darwin) are stored with 1
		// second granularity, so the timestamp checks will fail unless
		// we wait at least a second. Sleeping 1.1s to be safe.
		if runtime.GOOS == "darwin" {
			time.Sleep(1100 * time.Millisecond)
		}

		modify(config, dir, loadPkg)

		pkg = loadPkg()

		if err := pkg.Compile(config, filepath.Join(dir, "out")); err != nil {
			t.Fatal("Got error when compiling:", err)
		}
		if shouldRecompile {
			if !pkg.rebuilt {
				t.Fatal("Package should have recompiled, but was not recompiled.")
			}
		} else {
			if pkg.rebuilt {
				t.Fatal("Package should not have needed to be recompiled, but was recompiled.")
			}
		}

		if err := pkg.Link(config, out); err != nil {
			t.Fatal("Got error while linking:", err)
		}
		if shouldRelink {
			if !pkg.rebuilt {
				t.Error("Package should have relinked, but was not relinked.")
			}
		} else {
			if pkg.rebuilt {
				t.Error("Package should not have needed to be relinked, but was relinked.")
			}
		}

		if stat, err := os.Stat(out); err == nil {
			if shouldRelink {
				if stat.ModTime() == firstTime {
					t.Error("Output timestamp should be different, but both were", firstTime)
				}
			} else {
				if stat.ModTime() != firstTime {
					t.Error("Output timestamp should be the same.")
					t.Error(" first:", firstTime)
					t.Error("second:", stat.ModTime())
				}
			}
		} else {
			t.Fatal("Failed to stat output file:", err)
		}

		after(pkg)
	})
}

// TestRebuildAfterNoChanges ensures that we don't rebuild if nothing
// changes
func TestRebuildAfterNoChanges(t *testing.T) {
	testBuildAgain(t, false, false, func(config *Config, dir string, loadPkg loadPkgFunc) {}, func(pkg *GoPackage) {})
}

// TestRebuildAfterTimestamp ensures that we don't rebuild because
// timestamps of important files have changed. We should only rebuild if the
// content hashes are different.
func TestRebuildAfterTimestampChange(t *testing.T) {
	testBuildAgain(t, false, false, func(config *Config, dir string, loadPkg loadPkgFunc) {
		// Ensure that we've spent some amount of time asleep
		time.Sleep(100 * time.Millisecond)

		newTime := time.Now().Local()
		os.Chtimes(filepath.Join(dir, "test.fact"), newTime, newTime)
		os.Chtimes(filepath.Join(dir, "main/main.go"), newTime, newTime)
		os.Chtimes(filepath.Join(dir, "a/a.go"), newTime, newTime)
		os.Chtimes(filepath.Join(dir, "a/b.go"), newTime, newTime)
		os.Chtimes(filepath.Join(dir, "b/a.go"), newTime, newTime)
	}, func(pkg *GoPackage) {})
}

// TestRebuildAfterGoChange ensures that we rebuild after a content change
// to a package's go file.
func TestRebuildAfterGoChange(t *testing.T) {
	testBuildAgain(t, true, true, func(config *Config, dir string, loadPkg loadPkgFunc) {
		if err := ioutil.WriteFile(filepath.Join(dir, "a", "a.go"), []byte(go_a_a+"\n"), 0666); err != nil {
			t.Fatal("Error writing a/a.go:", err)
		}
	}, func(pkg *GoPackage) {
		if !pkg.directDeps[0].rebuilt {
			t.Fatal("android/soong/a should have rebuilt")
		}
		if !pkg.directDeps[1].rebuilt {
			t.Fatal("android/soong/b should have rebuilt")
		}
	})
}

// TestRebuildAfterMainChange ensures that we don't rebuild any dependencies
// if only the main package's go files are touched.
func TestRebuildAfterMainChange(t *testing.T) {
	testBuildAgain(t, true, true, func(config *Config, dir string, loadPkg loadPkgFunc) {
		if err := ioutil.WriteFile(filepath.Join(dir, "main", "main.go"), []byte(go_main_main+"\n"), 0666); err != nil {
			t.Fatal("Error writing main/main.go:", err)
		}
	}, func(pkg *GoPackage) {
		if pkg.directDeps[0].rebuilt {
			t.Fatal("android/soong/a should not have rebuilt")
		}
		if pkg.directDeps[1].rebuilt {
			t.Fatal("android/soong/b should not have rebuilt")
		}
	})
}

// TestRebuildAfterRemoveOut ensures that we rebuild if the output file is
// missing, even if everything else doesn't need rebuilding.
func TestRebuildAfterRemoveOut(t *testing.T) {
	testBuildAgain(t, false, true, func(config *Config, dir string, loadPkg loadPkgFunc) {
		if err := os.Remove(filepath.Join(dir, "out", "test")); err != nil {
			t.Fatal("Failed to remove output:", err)
		}
	}, func(pkg *GoPackage) {})
}

// TestRebuildAfterPartialBuild ensures that even if the build was interrupted
// between the recompile and relink stages, we'll still relink when we run again.
func TestRebuildAfterPartialBuild(t *testing.T) {
	testBuildAgain(t, false, true, func(config *Config, dir string, loadPkg loadPkgFunc) {
		if err := ioutil.WriteFile(filepath.Join(dir, "main", "main.go"), []byte(go_main_main+"\n"), 0666); err != nil {
			t.Fatal("Error writing main/main.go:", err)
		}

		pkg := loadPkg()

		if err := pkg.Compile(config, filepath.Join(dir, "out")); err != nil {
			t.Fatal("Got error when compiling:", err)
		}
		if !pkg.rebuilt {
			t.Fatal("Package should have recompiled, but was not recompiled.")
		}
	}, func(pkg *GoPackage) {})
}

// BenchmarkInitialBuild computes how long a clean build takes (for tiny test
// inputs).
func BenchmarkInitialBuild(b *testing.B) {
	for i := 0; i < b.N; i++ {
		setupDir(b, func(config *Config, dir string, loadPkg loadPkgFunc) {
			pkg := loadPkg()
			if err := pkg.Compile(config, filepath.Join(dir, "out")); err != nil {
				b.Fatal("Got error when compiling:", err)
			}

			if err := pkg.Link(config, filepath.Join(dir, "out", "test")); err != nil {
				b.Fatal("Got error when linking:", err)
			}
		})
	}
}

// BenchmarkMinIncrementalBuild computes how long an incremental build that
// doesn't actually need to build anything takes.
func BenchmarkMinIncrementalBuild(b *testing.B) {
	setupDir(b, func(config *Config, dir string, loadPkg loadPkgFunc) {
		pkg := loadPkg()

		if err := pkg.Compile(config, filepath.Join(dir, "out")); err != nil {
			b.Fatal("Got error when compiling:", err)
		}

		if err := pkg.Link(config, filepath.Join(dir, "out", "test")); err != nil {
			b.Fatal("Got error when linking:", err)
		}

		b.ResetTimer()

		for i := 0; i < b.N; i++ {
			pkg := loadPkg()

			if err := pkg.Compile(config, filepath.Join(dir, "out")); err != nil {
				b.Fatal("Got error when compiling:", err)
			}

			if err := pkg.Link(config, filepath.Join(dir, "out", "test")); err != nil {
				b.Fatal("Got error when linking:", err)
			}

			if pkg.rebuilt {
				b.Fatal("Should not have rebuilt anything")
			}
		}
	})
}

///////////////////////////////////////////////////////
// Templates used to create fake compilable packages //
///////////////////////////////////////////////////////

const go_main_main = `
package main
import (
	"fmt"
	"android/soong/a"
	"android/soong/b"
)
func main() {
	fmt.Println(a.Stdout, b.Stdout)
}
`

const go_a_a = `
package a
import "os"
var Stdout = os.Stdout
`

const go_a_b = `
package a
`

const go_b_a = `
package b
import "android/soong/a"
var Stdout = a.Stdout
`

type T interface {
	Fatal(args ...interface{})
	Fatalf(format string, args ...interface{})
}

type loadPkgFunc func() *GoPackage

func setupDir(t T, test func(config *Config, dir string, loadPkg loadPkgFunc)) {
	dir, err := ioutil.TempDir("", "test")
	if err != nil {
		t.Fatalf("Error creating temporary directory: %#v", err)
	}
	defer os.RemoveAll(dir)

	writeFile := func(name, contents string) {
		if err := ioutil.WriteFile(filepath.Join(dir, name), []byte(contents), 0666); err != nil {
			t.Fatalf("Error writing %q: %#v", name, err)
		}
	}
	mkdir := func(name string) {
		if err := os.Mkdir(filepath.Join(dir, name), 0777); err != nil {
			t.Fatalf("Error creating %q directory: %#v", name, err)
		}
	}
	mkdir("main")
	mkdir("a")
	mkdir("b")
	writeFile("main/main.go", go_main_main)
	writeFile("a/a.go", go_a_a)
	writeFile("a/b.go", go_a_b)
	writeFile("b/a.go", go_b_a)

	config := &Config{}
	config.Map("android/soong", dir)

	loadPkg := func() *GoPackage {
		pkg := &GoPackage{
			Name: "main",
		}
		if err := pkg.FindDeps(config, filepath.Join(dir, "main")); err != nil {
			t.Fatalf("Error finding deps: %v", err)
		}
		return pkg
	}

	test(config, dir, loadPkg)
}
