// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package profilescmdline_test

import (
	"bufio"
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"reflect"
	"regexp"
	"runtime"
	"strings"
	"sync"
	"testing"

	"v.io/jiri/jiri"
	"v.io/jiri/jiritest"
	"v.io/jiri/profiles"
	"v.io/jiri/profiles/profilescmdline"
	"v.io/jiri/profiles/profilesreader"
	"v.io/x/lib/envvar"
	"v.io/x/lib/gosh"
)

func TestManagerArgs(t *testing.T) {
	profilescmdline.Reset()
	p := parent
	profilescmdline.RegisterManagementCommands(&p, "", "", jiri.ProfilesRootDir)
	if got, want := len(p.Children), 5; got != want {
		t.Errorf("got %v, want %v", got, want)
	}
	type cl struct {
		args string
		n    int
	}
	cls := map[string]cl{
		"install":   cl{"--profiles-db=db --profiles-dir=root --target=arch-os --env=a=b,c=d --force=false", 5},
		"uninstall": cl{"--profiles-db=db --profiles-dir=root --target=arch-os --all-targets --v", 5},
		"cleanup":   cl{"--profiles-db=db --profiles-dir=root --gc --rm-all --v", 5},
		"update":    cl{"--profiles-db=db --profiles-dir=root -v", 3},
		"available": cl{"-v", 1},
	}
	for _, c := range p.Children {
		args := cls[c.Name].args
		if err := c.Flags.Parse(strings.Split(args, " ")); err != nil {
			t.Errorf("failed to parse for %s: %s: %v", c.Name, args, err)
			continue
		}
		if got, want := c.Flags.NFlag(), cls[c.Name].n; got != want {
			t.Errorf("%s: got %v, want %v", c.Name, got, want)
		}
	}
}

var (
	buildInstallersOnce, buildJiriOnce     sync.Once
	buildInstallersBindir, buildJiriBindir = "", ""
)

func newShell(t *testing.T) *gosh.Shell {
	fatalf := func(format string, args ...interface{}) {
		_, file, line, _ := runtime.Caller(3)
		loc := fmt.Sprintf("%s:%d: ", filepath.Base(file), line)
		fmt.Fprintf(os.Stderr, loc+format+"\n", args...)
		t.FailNow()
	}
	return gosh.NewShell(gosh.Opts{Fatalf: fatalf, Logf: t.Logf})
}

func buildInstallers(t *testing.T) string {
	buildInstallersOnce.Do(func() {
		sh := newShell(t)
		prefix := "v.io/jiri/profiles/profilescmdline/internal/"
		sh.BuildGoPkg("v.io/jiri", "-o", "jiri")
		sh.BuildGoPkg(prefix+"i1", "-o", "jiri-profile-i1")
		sh.BuildGoPkg(prefix+"i2", "-o", "jiri-profile-i2")
		buildInstallersBindir = sh.Opts.BinDir
	})
	return buildInstallersBindir
}

func buildJiri(t *testing.T) string {
	buildJiriOnce.Do(func() {
		sh := newShell(t)
		sh.BuildGoPkg("v.io/jiri", "-o", "jiri")
		buildJiriBindir = sh.Opts.BinDir
	})
	return buildJiriBindir
}

func run(sh *gosh.Shell, dir, bin string, args ...string) string {
	cmd := sh.Cmd(filepath.Join(dir, bin), args...)
	if testing.Verbose() {
		cmd.PropagateOutput = true
	}
	return cmd.Stdout()
}

func TestManagerAvailable(t *testing.T) {
	fake, cleanup := jiritest.NewFakeJiriRoot(t)
	defer cleanup()
	dir, sh := buildInstallers(t), newShell(t)
	sh.Vars["JIRI_ROOT"] = fake.X.Root
	sh.Vars["PATH"] = prependToPath(dir, os.Getenv("PATH"))
	stdout := run(sh, dir, "jiri", "profile", "available", "-v")
	for _, installer := range []string{"i1", "i2"} {
		re := regexp.MustCompile("Available Subcommands:.*profile-" + installer + ".*\n")
		if got := stdout; !re.MatchString(got) {
			t.Errorf("%v does not match %v\n", got, re.String())
		}
		if got, want := stdout, installer+":eg"; !strings.Contains(got, want) {
			t.Errorf("%v does not contain %v\n", got, want)
		}
	}
	os.RemoveAll(filepath.Join(fake.X.Root, jiri.ProfilesDBDir))
	stdout = run(sh, dir, "jiri", "profile", "available", "-v")
	if got, want := strings.TrimSpace(stdout), "Available Subcommands:"; got != want {
		t.Errorf("got %v, want %v", got, want)
	}
}

func loc() string {
	_, file, line, _ := runtime.Caller(2)
	return fmt.Sprintf("%s:%d", filepath.Base(file), line)
}
func exists(filename string) bool {
	_, err := os.Stat(filename)
	return err == nil
}

func contains(t *testing.T, filename, want string) {
	o, err := ioutil.ReadFile(filename)
	if err != nil {
		t.Fatal(err)
	}
	if got := string(o); got != want {
		t.Errorf("%s: %s: got %v, want %v", loc(), filename, got, want)
	}
}

func cat(msg, filename string) {
	o, err := ioutil.ReadFile(filename)
	if err != nil {
		panic(err)
	}
	fmt.Fprintln(os.Stderr, msg)
	fmt.Fprintln(os.Stderr, string(o))
	fmt.Fprintln(os.Stderr, msg)
}

func removeDate(s string) string {
	var result bytes.Buffer
	scanner := bufio.NewScanner(bytes.NewBufferString(s))
	re := regexp.MustCompile("(.*) date=\".*\"")
	for scanner.Scan() {
		result.WriteString(re.ReplaceAllString(scanner.Text(), "$1"))
		result.WriteString("\n")
	}
	return strings.TrimSpace(result.String())
}

func cmpFiles(t *testing.T, gotFilename, wantFilename string) {
	g, err := ioutil.ReadFile(gotFilename)
	if err != nil {
		t.Fatal(err)
	}
	w, err := ioutil.ReadFile(wantFilename)
	if err != nil {
		t.Fatal(err)
	}
	if got, want := removeDate(strings.TrimSpace(string(g))), removeDate(strings.TrimSpace(string(w))); got != want {
		t.Errorf("%s: got %v, want %v from %q and %q", loc(), got, want, gotFilename, wantFilename)
	}
}

func prependToPath(dir, path string) string {
	existingPath := envvar.SplitTokens(path, ":")
	return envvar.JoinTokens(append([]string{dir}, existingPath...), ":")
}

func TestManagerInstallUninstall(t *testing.T) {
	fake, cleanup := jiritest.NewFakeJiriRoot(t)
	defer cleanup()
	dir, sh := buildInstallers(t), newShell(t)
	sh.Vars["JIRI_ROOT"] = fake.X.Root
	sh.Vars["PATH"] = prependToPath(dir, os.Getenv("PATH"))

	run(sh, dir, "jiri", "profile", "list", "-v")

	i1 := filepath.Join(fake.X.Root, ".jiri_root/profile_db/i1")
	i2 := filepath.Join(fake.X.Root, ".jiri_root/profile_db/i2")

	run(sh, dir, "jiri", "profile", "install", "--target=arch-os", "i1:eg", "i2:eg")
	for _, installer := range []string{"i1", "i2"} {
		tdir := filepath.Join(fake.X.Root, jiri.ProfilesRootDir, installer, "eg", "arch_os")
		contains(t, filepath.Join(tdir, "version"), "3")
		contains(t, filepath.Join(tdir, "3"), "3")
	}
	cmpFiles(t, i1, filepath.Join("testdata", "i1a.xml"))
	cmpFiles(t, i2, filepath.Join("testdata", "i2a.xml"))

	run(sh, dir, "jiri", "profile", "install", "--target=arch-os@2", "i1:eg", "i2:eg")
	// Installs are idempotent.
	run(sh, dir, "jiri", "profile", "install", "--target=arch-os@2", "i1:eg", "i2:eg")
	for _, installer := range []string{"i1", "i2"} {
		tdir := filepath.Join(fake.X.Root, jiri.ProfilesRootDir, installer, "eg", "arch_os")
		contains(t, filepath.Join(tdir, "version"), "2")
		contains(t, filepath.Join(tdir, "3"), "3")
		contains(t, filepath.Join(tdir, "2"), "2")
	}

	cmpFiles(t, i1, filepath.Join("testdata", "i1b.xml"))
	cmpFiles(t, i2, filepath.Join("testdata", "i2b.xml"))

	run(sh, dir, "jiri", "profile", "uninstall", "--target=arch-os@2", "i1:eg", "i2:eg")
	for _, installer := range []string{"i1", "i2"} {
		tdir := filepath.Join(fake.X.Root, jiri.ProfilesRootDir, installer, "eg", "arch_os")
		contains(t, filepath.Join(tdir, "version"), "2")
		contains(t, filepath.Join(tdir, "3"), "3")
		if got, want := exists(filepath.Join(tdir, "2")), false; got != want {
			t.Errorf("%s: got %v, want %v", filepath.Join(tdir, "2"), got, want)
		}
	}
	cmpFiles(t, i1, filepath.Join("testdata", "i1c.xml"))
	cmpFiles(t, i2, filepath.Join("testdata", "i2c.xml"))

	// Put v2 back.
	run(sh, dir, "jiri", "profile", "list", "-v")
	run(sh, dir, "jiri", "profile", "install", "--target=arch-os@2", "i1:eg", "i2:eg")
	cmpFiles(t, i1, filepath.Join("testdata", "i1b.xml"))
	cmpFiles(t, i2, filepath.Join("testdata", "i2b.xml"))
}

func TestManagerUpdate(t *testing.T) {
	fake, cleanup := jiritest.NewFakeJiriRoot(t)
	defer cleanup()
	dir, sh := buildInstallers(t), newShell(t)
	sh.Vars["JIRI_ROOT"] = fake.X.Root
	sh.Vars["PATH"] = dir

	i1 := filepath.Join(fake.X.Root, ".jiri_root/profile_db/i1")
	i2 := filepath.Join(fake.X.Root, ".jiri_root/profile_db/i2")

	run(sh, dir, "jiri", "profile", "install", "--target=arch-os@2", "i1:eg", "i2:eg")
	cmpFiles(t, i1, filepath.Join("testdata", "i1d.xml"))
	cmpFiles(t, i2, filepath.Join("testdata", "i2d.xml"))

	run(sh, dir, "jiri", "profile", "update")
	cmpFiles(t, i1, filepath.Join("testdata", "i1e.xml"))
	cmpFiles(t, i2, filepath.Join("testdata", "i2e.xml"))

	run(sh, dir, "jiri", "profile", "cleanup", "-gc")
	cmpFiles(t, i1, filepath.Join("testdata", "i1f.xml"))
	cmpFiles(t, i2, filepath.Join("testdata", "i2f.xml"))
}

// Test using a fake jiri root.
func TestJiriFakeRoot(t *testing.T) {
	fake, cleanup := jiritest.NewFakeJiriRoot(t)
	defer cleanup()
	profilesDBDir := filepath.Join(fake.X.Root, jiri.ProfilesDBDir)
	_ = cleanup
	pdb := profiles.NewDB()
	t1, err := profiles.NewTarget("cpu1-os1@1", "A=B,C=D")
	if err != nil {
		t.Fatal(err)
	}
	pdb.InstallProfile("test", "b", "")
	if err := pdb.AddProfileTarget("test", "b", t1); err != nil {
		t.Fatal(err)
	}
	if err := pdb.Write(fake.X, "test", profilesDBDir); err != nil {
		t.Fatal(err)
	}

	rd, err := profilesreader.NewReader(fake.X, profilesreader.UseProfiles, profilesDBDir)
	if err != nil {
		t.Fatal(err)
	}

	if got, want := rd.ProfileNames(), []string{"test:b"}; !reflect.DeepEqual(got, want) {
		t.Errorf("got %v, want %v", got, want)
	}

	dir, sh := buildJiri(t), newShell(t)
	sh.Vars["JIRI_ROOT"] = fake.X.Root
	sh.Vars["PATH"] = prependToPath(dir, os.Getenv("PATH"))
	run(sh, dir, "jiri", "profile", "list", "-v")
}
