// Copyright 2014 The Go 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 main

import (
	"bufio"
	"bytes"
	"cmd/internal/archive"
	"fmt"
	"internal/testenv"
	"io"
	"io/fs"
	"os"
	"os/exec"
	"path/filepath"
	"testing"
	"time"
)

// tmpDir creates a temporary directory and returns its name.
func tmpDir(t *testing.T) string {
	name, err := os.MkdirTemp("", "pack")
	if err != nil {
		t.Fatal(err)
	}
	return name
}

// testCreate creates an archive in the specified directory.
func testCreate(t *testing.T, dir string) {
	name := filepath.Join(dir, "pack.a")
	ar := openArchive(name, os.O_RDWR|os.O_CREATE, nil)
	// Add an entry by hand.
	ar.addFile(helloFile.Reset())
	ar.a.File().Close()
	// Now check it.
	ar = openArchive(name, os.O_RDONLY, []string{helloFile.name})
	var buf bytes.Buffer
	stdout = &buf
	verbose = true
	defer func() {
		stdout = os.Stdout
		verbose = false
	}()
	ar.scan(ar.printContents)
	ar.a.File().Close()
	result := buf.String()
	// Expect verbose output plus file contents.
	expect := fmt.Sprintf("%s\n%s", helloFile.name, helloFile.contents)
	if result != expect {
		t.Fatalf("expected %q got %q", expect, result)
	}
}

// Test that we can create an archive, write to it, and get the same contents back.
// Tests the rv and then the pv command on a new archive.
func TestCreate(t *testing.T) {
	dir := tmpDir(t)
	defer os.RemoveAll(dir)
	testCreate(t, dir)
}

// Test that we can create an archive twice with the same name (Issue 8369).
func TestCreateTwice(t *testing.T) {
	dir := tmpDir(t)
	defer os.RemoveAll(dir)
	testCreate(t, dir)
	testCreate(t, dir)
}

// Test that we can create an archive, put some files in it, and get back a correct listing.
// Tests the tv command.
func TestTableOfContents(t *testing.T) {
	dir := tmpDir(t)
	defer os.RemoveAll(dir)
	name := filepath.Join(dir, "pack.a")
	ar := openArchive(name, os.O_RDWR|os.O_CREATE, nil)

	// Add some entries by hand.
	ar.addFile(helloFile.Reset())
	ar.addFile(goodbyeFile.Reset())
	ar.a.File().Close()

	// Now print it.
	var buf bytes.Buffer
	stdout = &buf
	verbose = true
	defer func() {
		stdout = os.Stdout
		verbose = false
	}()
	ar = openArchive(name, os.O_RDONLY, nil)
	ar.scan(ar.tableOfContents)
	ar.a.File().Close()
	result := buf.String()
	// Expect verbose listing.
	expect := fmt.Sprintf("%s\n%s\n", helloFile.Entry(), goodbyeFile.Entry())
	if result != expect {
		t.Fatalf("expected %q got %q", expect, result)
	}

	// Do it again without verbose.
	verbose = false
	buf.Reset()
	ar = openArchive(name, os.O_RDONLY, nil)
	ar.scan(ar.tableOfContents)
	ar.a.File().Close()
	result = buf.String()
	// Expect non-verbose listing.
	expect = fmt.Sprintf("%s\n%s\n", helloFile.name, goodbyeFile.name)
	if result != expect {
		t.Fatalf("expected %q got %q", expect, result)
	}

	// Do it again with file list arguments.
	verbose = false
	buf.Reset()
	ar = openArchive(name, os.O_RDONLY, []string{helloFile.name})
	ar.scan(ar.tableOfContents)
	ar.a.File().Close()
	result = buf.String()
	// Expect only helloFile.
	expect = fmt.Sprintf("%s\n", helloFile.name)
	if result != expect {
		t.Fatalf("expected %q got %q", expect, result)
	}
}

// Test that we can create an archive, put some files in it, and get back a file.
// Tests the x command.
func TestExtract(t *testing.T) {
	dir := tmpDir(t)
	defer os.RemoveAll(dir)
	name := filepath.Join(dir, "pack.a")
	ar := openArchive(name, os.O_RDWR|os.O_CREATE, nil)
	// Add some entries by hand.
	ar.addFile(helloFile.Reset())
	ar.addFile(goodbyeFile.Reset())
	ar.a.File().Close()
	// Now extract one file. We chdir to the directory of the archive for simplicity.
	pwd, err := os.Getwd()
	if err != nil {
		t.Fatal("os.Getwd: ", err)
	}
	err = os.Chdir(dir)
	if err != nil {
		t.Fatal("os.Chdir: ", err)
	}
	defer func() {
		err := os.Chdir(pwd)
		if err != nil {
			t.Fatal("os.Chdir: ", err)
		}
	}()
	ar = openArchive(name, os.O_RDONLY, []string{goodbyeFile.name})
	ar.scan(ar.extractContents)
	ar.a.File().Close()
	data, err := os.ReadFile(goodbyeFile.name)
	if err != nil {
		t.Fatal(err)
	}
	// Expect contents of file.
	result := string(data)
	expect := goodbyeFile.contents
	if result != expect {
		t.Fatalf("expected %q got %q", expect, result)
	}
}

// Test that pack-created archives can be understood by the tools.
func TestHello(t *testing.T) {
	testenv.MustHaveGoBuild(t)

	dir := tmpDir(t)
	defer os.RemoveAll(dir)
	hello := filepath.Join(dir, "hello.go")
	prog := `
		package main
		func main() {
			println("hello world")
		}
	`
	err := os.WriteFile(hello, []byte(prog), 0666)
	if err != nil {
		t.Fatal(err)
	}

	run := func(args ...string) string {
		return doRun(t, dir, args...)
	}

	goBin := testenv.GoToolPath(t)
	run(goBin, "build", "cmd/pack") // writes pack binary to dir
	run(goBin, "tool", "compile", "hello.go")
	run("./pack", "grc", "hello.a", "hello.o")
	run(goBin, "tool", "link", "-o", "a.out", "hello.a")
	out := run("./a.out")
	if out != "hello world\n" {
		t.Fatalf("incorrect output: %q, want %q", out, "hello world\n")
	}
}

// Test that pack works with very long lines in PKGDEF.
func TestLargeDefs(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping in -short mode")
	}
	testenv.MustHaveGoBuild(t)

	dir := tmpDir(t)
	defer os.RemoveAll(dir)
	large := filepath.Join(dir, "large.go")
	f, err := os.Create(large)
	if err != nil {
		t.Fatal(err)
	}
	b := bufio.NewWriter(f)

	printf := func(format string, args ...interface{}) {
		_, err := fmt.Fprintf(b, format, args...)
		if err != nil {
			t.Fatalf("Writing to %s: %v", large, err)
		}
	}

	printf("package large\n\ntype T struct {\n")
	for i := 0; i < 1000; i++ {
		printf("f%d int `tag:\"", i)
		for j := 0; j < 100; j++ {
			printf("t%d=%d,", j, j)
		}
		printf("\"`\n")
	}
	printf("}\n")
	if err = b.Flush(); err != nil {
		t.Fatal(err)
	}
	if err = f.Close(); err != nil {
		t.Fatal(err)
	}

	main := filepath.Join(dir, "main.go")
	prog := `
		package main
		import "large"
		var V large.T
		func main() {
			println("ok")
		}
	`
	err = os.WriteFile(main, []byte(prog), 0666)
	if err != nil {
		t.Fatal(err)
	}

	run := func(args ...string) string {
		return doRun(t, dir, args...)
	}

	goBin := testenv.GoToolPath(t)
	run(goBin, "build", "cmd/pack") // writes pack binary to dir
	run(goBin, "tool", "compile", "large.go")
	run("./pack", "grc", "large.a", "large.o")
	run(goBin, "tool", "compile", "-I", ".", "main.go")
	run(goBin, "tool", "link", "-L", ".", "-o", "a.out", "main.o")
	out := run("./a.out")
	if out != "ok\n" {
		t.Fatalf("incorrect output: %q, want %q", out, "ok\n")
	}
}

// Test that "\n!\n" inside export data doesn't result in a truncated
// package definition when creating a .a archive from a .o Go object.
func TestIssue21703(t *testing.T) {
	testenv.MustHaveGoBuild(t)

	dir := tmpDir(t)
	defer os.RemoveAll(dir)

	const aSrc = `package a; const X = "\n!\n"`
	err := os.WriteFile(filepath.Join(dir, "a.go"), []byte(aSrc), 0666)
	if err != nil {
		t.Fatal(err)
	}

	const bSrc = `package b; import _ "a"`
	err = os.WriteFile(filepath.Join(dir, "b.go"), []byte(bSrc), 0666)
	if err != nil {
		t.Fatal(err)
	}

	run := func(args ...string) string {
		return doRun(t, dir, args...)
	}

	goBin := testenv.GoToolPath(t)
	run(goBin, "build", "cmd/pack") // writes pack binary to dir
	run(goBin, "tool", "compile", "a.go")
	run("./pack", "c", "a.a", "a.o")
	run(goBin, "tool", "compile", "-I", ".", "b.go")
}

// Test the "c" command can "see through" the archive generated by the compiler.
// This is peculiar. (See issue #43271)
func TestCreateWithCompilerObj(t *testing.T) {
	testenv.MustHaveGoBuild(t)

	dir := tmpDir(t)
	defer os.RemoveAll(dir)
	src := filepath.Join(dir, "p.go")
	prog := "package p; var X = 42\n"
	err := os.WriteFile(src, []byte(prog), 0666)
	if err != nil {
		t.Fatal(err)
	}

	run := func(args ...string) string {
		return doRun(t, dir, args...)
	}

	goBin := testenv.GoToolPath(t)
	run(goBin, "build", "cmd/pack") // writes pack binary to dir
	run(goBin, "tool", "compile", "-pack", "-o", "p.a", "p.go")
	run("./pack", "c", "packed.a", "p.a")
	fi, err := os.Stat(filepath.Join(dir, "p.a"))
	if err != nil {
		t.Fatalf("stat p.a failed: %v", err)
	}
	fi2, err := os.Stat(filepath.Join(dir, "packed.a"))
	if err != nil {
		t.Fatalf("stat packed.a failed: %v", err)
	}
	// For compiler-generated object file, the "c" command is
	// expected to get (essentially) the same file back, instead
	// of packing it into a new archive with a single entry.
	if want, got := fi.Size(), fi2.Size(); want != got {
		t.Errorf("packed file with different size: want %d, got %d", want, got)
	}

	// Test -linkobj flag as well.
	run(goBin, "tool", "compile", "-linkobj", "p2.a", "-o", "p.x", "p.go")
	run("./pack", "c", "packed2.a", "p2.a")
	fi, err = os.Stat(filepath.Join(dir, "p2.a"))
	if err != nil {
		t.Fatalf("stat p2.a failed: %v", err)
	}
	fi2, err = os.Stat(filepath.Join(dir, "packed2.a"))
	if err != nil {
		t.Fatalf("stat packed2.a failed: %v", err)
	}
	if want, got := fi.Size(), fi2.Size(); want != got {
		t.Errorf("packed file with different size: want %d, got %d", want, got)
	}

	run("./pack", "c", "packed3.a", "p.x")
	fi, err = os.Stat(filepath.Join(dir, "p.x"))
	if err != nil {
		t.Fatalf("stat p.x failed: %v", err)
	}
	fi2, err = os.Stat(filepath.Join(dir, "packed3.a"))
	if err != nil {
		t.Fatalf("stat packed3.a failed: %v", err)
	}
	if want, got := fi.Size(), fi2.Size(); want != got {
		t.Errorf("packed file with different size: want %d, got %d", want, got)
	}
}

// Test the "r" command creates the output file if it does not exist.
func TestRWithNonexistentFile(t *testing.T) {
	testenv.MustHaveGoBuild(t)

	dir := tmpDir(t)
	defer os.RemoveAll(dir)
	src := filepath.Join(dir, "p.go")
	prog := "package p; var X = 42\n"
	err := os.WriteFile(src, []byte(prog), 0666)
	if err != nil {
		t.Fatal(err)
	}

	run := func(args ...string) string {
		return doRun(t, dir, args...)
	}

	goBin := testenv.GoToolPath(t)
	run(goBin, "build", "cmd/pack") // writes pack binary to dir
	run(goBin, "tool", "compile", "-o", "p.o", "p.go")
	run("./pack", "r", "p.a", "p.o") // should succeed
}

// doRun runs a program in a directory and returns the output.
func doRun(t *testing.T, dir string, args ...string) string {
	cmd := exec.Command(args[0], args[1:]...)
	cmd.Dir = dir
	out, err := cmd.CombinedOutput()
	if err != nil {
		t.Fatalf("%v: %v\n%s", args, err, string(out))
	}
	return string(out)
}

// Fake implementation of files.

var helloFile = &FakeFile{
	name:     "hello",
	contents: "hello world", // 11 bytes, an odd number.
	mode:     0644,
}

var goodbyeFile = &FakeFile{
	name:     "goodbye",
	contents: "Sayonara, Jim", // 13 bytes, another odd number.
	mode:     0644,
}

// FakeFile implements FileLike and also fs.FileInfo.
type FakeFile struct {
	name     string
	contents string
	mode     fs.FileMode
	offset   int
}

// Reset prepares a FakeFile for reuse.
func (f *FakeFile) Reset() *FakeFile {
	f.offset = 0
	return f
}

// FileLike methods.

func (f *FakeFile) Name() string {
	// A bit of a cheat: we only have a basename, so that's also ok for FileInfo.
	return f.name
}

func (f *FakeFile) Stat() (fs.FileInfo, error) {
	return f, nil
}

func (f *FakeFile) Read(p []byte) (int, error) {
	if f.offset >= len(f.contents) {
		return 0, io.EOF
	}
	n := copy(p, f.contents[f.offset:])
	f.offset += n
	return n, nil
}

func (f *FakeFile) Close() error {
	return nil
}

// fs.FileInfo methods.

func (f *FakeFile) Size() int64 {
	return int64(len(f.contents))
}

func (f *FakeFile) Mode() fs.FileMode {
	return f.mode
}

func (f *FakeFile) ModTime() time.Time {
	return time.Time{}
}

func (f *FakeFile) IsDir() bool {
	return false
}

func (f *FakeFile) Sys() interface{} {
	return nil
}

// Special helpers.

func (f *FakeFile) Entry() *archive.Entry {
	return &archive.Entry{
		Name:  f.name,
		Mtime: 0, // Defined to be zero.
		Uid:   0, // Ditto.
		Gid:   0, // Ditto.
		Mode:  f.mode,
		Data:  archive.Data{Size: int64(len(f.contents))},
	}
}
