// Copyright 2020 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 (
	"bytes"
	"fmt"
	"go/parser"
	"go/token"
	"html/template"
	"strings"
	"testing"
)

func TestImports(t *testing.T) {
	t.Run("importName", func(t *testing.T) {
		cases := []struct {
			src   string
			ident string
		}{
			{`"syscall"`, "syscall"},
			{`. "foobar"`, "."},
			{`"go/ast"`, "ast"},
			{`moo "go/format"`, "moo"},
			{`. "go/token"`, "."},
			{`"golang.org/x/sys/unix"`, "unix"},
			{`nix "golang.org/x/sys/unix"`, "nix"},
			{`_ "golang.org/x/sys/unix"`, "_"},
		}

		for _, c := range cases {
			pkgSrc := fmt.Sprintf("package main\nimport %s", c.src)

			f, err := parser.ParseFile(token.NewFileSet(), "", pkgSrc, parser.ImportsOnly)
			if err != nil {
				t.Error(err)
				continue
			}
			if len(f.Imports) != 1 {
				t.Errorf("Got %d imports, expected 1", len(f.Imports))
				continue
			}

			got, err := importName(f.Imports[0])
			if err != nil {
				t.Fatal(err)
			}
			if got != c.ident {
				t.Errorf("Got %q, expected %q", got, c.ident)
			}
		}
	})

	t.Run("filterImports", func(t *testing.T) {
		cases := []struct{ before, after string }{
			{`package test

			import (
				"foo"
				"bar"
			)`,
				"package test\n"},
			{`package test

			import (
				"foo"
				"bar"
			)

			func useFoo() { foo.Usage() }`,
				`package test

import (
	"foo"
)

func useFoo() { foo.Usage() }
`},
		}
		for _, c := range cases {
			got, err := filterImports([]byte(c.before))
			if err != nil {
				t.Error(err)
			}

			if string(got) != c.after {
				t.Errorf("Got:\n%s\nExpected:\n%s\n", got, c.after)
			}
		}
	})
}

func TestMerge(t *testing.T) {
	// Input architecture files
	inTmpl := template.Must(template.New("input").Parse(`
// Package comments

// build directives for arch{{.}}

//go:build goos && arch{{.}}
// +build goos,arch{{.}}

package main

/*
#include <stdint.h>
#include <stddef.h>
int utimes(uintptr_t, uintptr_t);
int utimensat(int, uintptr_t, uintptr_t, int);
*/
import "C"

// The imports
import (
	"commonDep"
	"uniqueDep{{.}}"
)

// Vars
var (
	commonVar = commonDep.Use("common")

	uniqueVar{{.}} = "unique{{.}}"
)

// Common free standing comment

// Common comment
const COMMON_INDEPENDENT = 1234
const UNIQUE_INDEPENDENT_{{.}} = "UNIQUE_INDEPENDENT_{{.}}"

// Group comment
const (
	COMMON_GROUP = "COMMON_GROUP"
	UNIQUE_GROUP_{{.}} = "UNIQUE_GROUP_{{.}}"
)

// Group2 comment
const (
	UNIQUE_GROUP21_{{.}} = "UNIQUE_GROUP21_{{.}}"
	UNIQUE_GROUP22_{{.}} = "UNIQUE_GROUP22_{{.}}"
)

// Group3 comment
const (
	sub1Common1 = 11
	sub1Unique2{{.}} = 12
	sub1Common3_LONG = 13

	sub2Unique1{{.}} = 21
	sub2Common2 = 22
	sub2Common3 = 23
	sub2Unique4{{.}} = 24
)

type commonInt int

type uniqueInt{{.}} int

func commonF() string {
	return commonDep.Use("common")
	}

func uniqueF() string {
	C.utimes(0, 0)
	return uniqueDep{{.}}.Use("{{.}}")
	}

// Group4 comment
const (
	sub3Common1 = 31
	sub3Unique2{{.}} = 32
	sub3Unique3{{.}} = 33
	sub3Common4 = 34

	sub4Common1, sub4Unique2{{.}} = 41, 42
	sub4Unique3{{.}}, sub4Common4 = 43, 44
)
`))

	// Filtered architecture files
	outTmpl := template.Must(template.New("output").Parse(`// Package comments

// build directives for arch{{.}}

//go:build goos && arch{{.}}
// +build goos,arch{{.}}

package main

/*
#include <stdint.h>
#include <stddef.h>
int utimes(uintptr_t, uintptr_t);
int utimensat(int, uintptr_t, uintptr_t, int);
*/
import "C"

// The imports
import (
	"commonDep"
	"uniqueDep{{.}}"
)

// Vars
var (
	commonVar = commonDep.Use("common")

	uniqueVar{{.}} = "unique{{.}}"
)

const UNIQUE_INDEPENDENT_{{.}} = "UNIQUE_INDEPENDENT_{{.}}"

// Group comment
const (
	UNIQUE_GROUP_{{.}} = "UNIQUE_GROUP_{{.}}"
)

// Group2 comment
const (
	UNIQUE_GROUP21_{{.}} = "UNIQUE_GROUP21_{{.}}"
	UNIQUE_GROUP22_{{.}} = "UNIQUE_GROUP22_{{.}}"
)

// Group3 comment
const (
	sub1Unique2{{.}} = 12

	sub2Unique1{{.}} = 21
	sub2Unique4{{.}} = 24
)

type uniqueInt{{.}} int

func uniqueF() string {
	C.utimes(0, 0)
	return uniqueDep{{.}}.Use("{{.}}")
}

// Group4 comment
const (
	sub3Unique2{{.}} = 32
	sub3Unique3{{.}} = 33

	sub4Common1, sub4Unique2{{.}} = 41, 42
	sub4Unique3{{.}}, sub4Common4 = 43, 44
)
`))

	const mergedFile = `// Package comments

package main

// The imports
import (
	"commonDep"
)

// Common free standing comment

// Common comment
const COMMON_INDEPENDENT = 1234

// Group comment
const (
	COMMON_GROUP = "COMMON_GROUP"
)

// Group3 comment
const (
	sub1Common1      = 11
	sub1Common3_LONG = 13

	sub2Common2 = 22
	sub2Common3 = 23
)

type commonInt int

func commonF() string {
	return commonDep.Use("common")
}

// Group4 comment
const (
	sub3Common1 = 31
	sub3Common4 = 34
)
`

	// Generate source code for different "architectures"
	var inFiles, outFiles []srcFile
	for _, arch := range strings.Fields("A B C D") {
		buf := new(bytes.Buffer)
		err := inTmpl.Execute(buf, arch)
		if err != nil {
			t.Fatal(err)
		}
		inFiles = append(inFiles, srcFile{"file" + arch, buf.Bytes()})

		buf = new(bytes.Buffer)
		err = outTmpl.Execute(buf, arch)
		if err != nil {
			t.Fatal(err)
		}
		outFiles = append(outFiles, srcFile{"file" + arch, buf.Bytes()})
	}

	t.Run("getCodeSet", func(t *testing.T) {
		got, err := getCodeSet(inFiles[0].src)
		if err != nil {
			t.Fatal(err)
		}

		expectedElems := []codeElem{
			{token.COMMENT, "Package comments\n"},
			{token.COMMENT, "build directives for archA\n"},
			{token.COMMENT, "+build goos,archA\n"},
			{token.CONST, `COMMON_INDEPENDENT = 1234`},
			{token.CONST, `UNIQUE_INDEPENDENT_A = "UNIQUE_INDEPENDENT_A"`},
			{token.CONST, `COMMON_GROUP = "COMMON_GROUP"`},
			{token.CONST, `UNIQUE_GROUP_A = "UNIQUE_GROUP_A"`},
			{token.CONST, `UNIQUE_GROUP21_A = "UNIQUE_GROUP21_A"`},
			{token.CONST, `UNIQUE_GROUP22_A = "UNIQUE_GROUP22_A"`},
			{token.CONST, `sub1Common1 = 11`},
			{token.CONST, `sub1Unique2A = 12`},
			{token.CONST, `sub1Common3_LONG = 13`},
			{token.CONST, `sub2Unique1A = 21`},
			{token.CONST, `sub2Common2 = 22`},
			{token.CONST, `sub2Common3 = 23`},
			{token.CONST, `sub2Unique4A = 24`},
			{token.CONST, `sub3Common1 = 31`},
			{token.CONST, `sub3Unique2A = 32`},
			{token.CONST, `sub3Unique3A = 33`},
			{token.CONST, `sub3Common4 = 34`},
			{token.CONST, `sub4Common1, sub4Unique2A = 41, 42`},
			{token.CONST, `sub4Unique3A, sub4Common4 = 43, 44`},
			{token.TYPE, `commonInt int`},
			{token.TYPE, `uniqueIntA int`},
			{token.FUNC, `func commonF() string {
	return commonDep.Use("common")
}`},
			{token.FUNC, `func uniqueF() string {
	C.utimes(0, 0)
	return uniqueDepA.Use("A")
}`},
		}
		expected := newCodeSet()
		for _, d := range expectedElems {
			expected.add(d)
		}

		if len(got.set) != len(expected.set) {
			t.Errorf("Got %d codeElems, expected %d", len(got.set), len(expected.set))
		}
		for expElem := range expected.set {
			if !got.has(expElem) {
				t.Errorf("Didn't get expected codeElem %#v", expElem)
			}
		}
		for gotElem := range got.set {
			if !expected.has(gotElem) {
				t.Errorf("Got unexpected codeElem %#v", gotElem)
			}
		}
	})

	t.Run("getCommonSet", func(t *testing.T) {
		got, err := getCommonSet(inFiles)
		if err != nil {
			t.Fatal(err)
		}

		expected := newCodeSet()
		expected.add(codeElem{token.COMMENT, "Package comments\n"})
		expected.add(codeElem{token.CONST, `COMMON_INDEPENDENT = 1234`})
		expected.add(codeElem{token.CONST, `COMMON_GROUP = "COMMON_GROUP"`})
		expected.add(codeElem{token.CONST, `sub1Common1 = 11`})
		expected.add(codeElem{token.CONST, `sub1Common3_LONG = 13`})
		expected.add(codeElem{token.CONST, `sub2Common2 = 22`})
		expected.add(codeElem{token.CONST, `sub2Common3 = 23`})
		expected.add(codeElem{token.CONST, `sub3Common1 = 31`})
		expected.add(codeElem{token.CONST, `sub3Common4 = 34`})
		expected.add(codeElem{token.TYPE, `commonInt int`})
		expected.add(codeElem{token.FUNC, `func commonF() string {
	return commonDep.Use("common")
}`})

		if len(got.set) != len(expected.set) {
			t.Errorf("Got %d codeElems, expected %d", len(got.set), len(expected.set))
		}
		for expElem := range expected.set {
			if !got.has(expElem) {
				t.Errorf("Didn't get expected codeElem %#v", expElem)
			}
		}
		for gotElem := range got.set {
			if !expected.has(gotElem) {
				t.Errorf("Got unexpected codeElem %#v", gotElem)
			}
		}
	})

	t.Run("filter(keepCommon)", func(t *testing.T) {
		commonSet, err := getCommonSet(inFiles)
		if err != nil {
			t.Fatal(err)
		}

		got, err := filter(inFiles[0].src, commonSet.keepCommon)
		expected := []byte(mergedFile)

		if !bytes.Equal(got, expected) {
			t.Errorf("Got:\n%s\nExpected:\n%s", addLineNr(got), addLineNr(expected))
			diffLines(t, got, expected)
		}
	})

	t.Run("filter(keepArchSpecific)", func(t *testing.T) {
		commonSet, err := getCommonSet(inFiles)
		if err != nil {
			t.Fatal(err)
		}

		for i := range inFiles {
			got, err := filter(inFiles[i].src, commonSet.keepArchSpecific)
			if err != nil {
				t.Fatal(err)
			}

			expected := outFiles[i].src

			if !bytes.Equal(got, expected) {
				t.Errorf("Got:\n%s\nExpected:\n%s", addLineNr(got), addLineNr(expected))
				diffLines(t, got, expected)
			}
		}
	})
}

func TestMergedName(t *testing.T) {
	t.Run("getValidGOOS", func(t *testing.T) {
		testcases := []struct {
			filename, goos string
			ok             bool
		}{
			{"zerrors_aix.go", "aix", true},
			{"zerrors_darwin.go", "darwin", true},
			{"zerrors_dragonfly.go", "dragonfly", true},
			{"zerrors_freebsd.go", "freebsd", true},
			{"zerrors_linux.go", "linux", true},
			{"zerrors_netbsd.go", "netbsd", true},
			{"zerrors_openbsd.go", "openbsd", true},
			{"zerrors_solaris.go", "solaris", true},
			{"zerrors_multics.go", "", false},
		}
		for _, tc := range testcases {
			goos, ok := getValidGOOS(tc.filename)
			if goos != tc.goos {
				t.Errorf("got GOOS %q, expected %q", goos, tc.goos)
			}
			if ok != tc.ok {
				t.Errorf("got ok %v, expected %v", ok, tc.ok)
			}
		}
	})
}

// Helper functions to diff test sources

func diffLines(t *testing.T, got, expected []byte) {
	t.Helper()

	gotLines := bytes.Split(got, []byte{'\n'})
	expLines := bytes.Split(expected, []byte{'\n'})

	i := 0
	for i < len(gotLines) && i < len(expLines) {
		if !bytes.Equal(gotLines[i], expLines[i]) {
			t.Errorf("Line %d: Got:\n%q\nExpected:\n%q", i+1, gotLines[i], expLines[i])
			return
		}
		i++
	}

	if i < len(gotLines) && i >= len(expLines) {
		t.Errorf("Line %d: got %q, expected EOF", i+1, gotLines[i])
	}
	if i >= len(gotLines) && i < len(expLines) {
		t.Errorf("Line %d: got EOF, expected %q", i+1, gotLines[i])
	}
}

func addLineNr(src []byte) []byte {
	lines := bytes.Split(src, []byte("\n"))
	for i, line := range lines {
		lines[i] = []byte(fmt.Sprintf("%d: %s", i+1, line))
	}
	return bytes.Join(lines, []byte("\n"))
}
