// 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.Error("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.Error("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.Fatalf("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)
}
