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

// +build darwin

package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"strings"
	"testing"

	"v.io/jiri"
	"v.io/jiri/tool"
)

func resetVars() {
	buildCgo = false
	buildFramework = false

	if sh != nil {
		sh.Cleanup()
	}
	sh = newShell()

	flagBuildMode = buildModeArchive
	flagBuildDirCgo = ""
	flagOutDirSwift = sh.MakeTempDir()
	flagProject = ""
	flagReleaseMode = false
	flagTargetArch = targetArchAll

	targetArchs = []string{} // gets set by parseBuildFlags()
	selectedProject = nil
	parseBuildFlags()
}

func TestMain(m *testing.M) {
	flag.Parse()
	resetVars()

	// Ensure we have our necessary go profiles installed
	installProfiles()

	ret := m.Run()
	if sh != nil {
		sh.Cleanup()
	}
	os.Exit(ret)
}

func installProfiles() {
	targets := []string{"arm64-ios", "amd64-ios"}
	for _, target := range targets {
		sh.Cmd("jiri", "profile", "install", "-target="+target, "v23:base").Run()
	}
}

func initForTest(t *testing.T) *jiri.X {
	resetVars()

	// Capture JIRI_ROOT using a relative path.  We need the real JIRI_ROOT as
	// the real of jiri-swift needs the proper profiles installed and itself calls
	// out to jiri via GOSH.
	root, err := filepath.Abs(filepath.Join("..", "..", "..", "..", "..", "..", ".."))
	if err != nil {
		t.Fatal(err)
	}
	// Sanity check that's correct
	if _, err := os.Stat(filepath.Join(root, "release", "swift")); err != nil {
		t.Fatal("Real JIRI_ROOT was not properly set: ", root)
	}

	verboseFlag := true
	jirix := &jiri.X{Context: tool.NewContext(tool.ContextOpts{Verbose: &verboseFlag}), Root: root}
	// Clean before testing
	runClean(jirix, []string{})
	return jirix
}

func TestParseProjectFlags(t *testing.T) {
	resetVars()
	if err := parseProjectFlag(); err == nil {
		t.Errorf("Expected error when no project is set")
	}
	flagProject = "VanadiumCore"
	if err := parseProjectFlag(); err != nil {
		t.Errorf("Expected no error for VandiumCore")
	}
	flagProject = "vanadiumcore"
	if err := parseProjectFlag(); err != nil {
		t.Errorf("Expected no error for vanadiumcore")
	}
	flagProject = "SyncbaseCore"
	if err := parseProjectFlag(); err != nil {
		t.Errorf("Expected no error for SyncbaseCore")
	}
	flagProject = "syncbasecore"
	if err := parseProjectFlag(); err != nil {
		t.Errorf("Expected no error for syncbasecore")
	}
	flagProject = "Something else"
	if err := parseProjectFlag(); err == nil {
		t.Errorf("Expected error non-project name")
	}
}

func TestParseBuildFlags(t *testing.T) {
	resetVars()
	// Test shared only working on amd64
	flagBuildMode = buildModeShared // should fail on all
	flagTargetArch = targetArchAll
	if err := parseBuildFlags(); err == nil {
		t.Errorf("Expected error in building all in shared mode")
	}
	flagTargetArch = targetArchArm
	if err := parseBuildFlags(); err == nil {
		t.Errorf("Expected error in building arm in shared mode")
	}
	flagTargetArch = targetArchArm64
	if err := parseBuildFlags(); err == nil {
		t.Errorf("Expected error in building arm64 in shared mode")
	}
	flagTargetArch = targetArchAmd64
	if err := parseBuildFlags(); err != nil {
		t.Errorf("Unexpected error setting to build amd64 in shared mode: %v", err)
	}

	flagBuildMode = buildModeArchive // should work on all
	flagTargetArch = targetArchAll
	if err := parseBuildFlags(); err != nil {
		t.Errorf("Unexpected error setting to build all in archive mode: %v", err)
	}
	flagTargetArch = targetArchArm
	if err := parseBuildFlags(); err == nil {
		t.Errorf("Expected 32-bit arm to fail as unsupported in archive mode: %v", err)
	}
	flagTargetArch = targetArchArm64
	if err := parseBuildFlags(); err != nil {
		t.Errorf("Unexpected error setting to build arm64 in archive mode: %v", err)
	}
	flagTargetArch = targetArchAmd64
	if err := parseBuildFlags(); err != nil {
		t.Errorf("Unexpected error setting to build amd64 in archive mode: %v", err)
	}
}

func TestParseBuildArgs(t *testing.T) {
	jirix := initForTest(t)
	// Default case -- no args
	if err := parseBuildArgs(jirix, []string{}); err != nil {
		t.Error(err)
		return
	}
	if !buildCgo || !buildFramework {
		t.Error("Default no args case didn't result in building cgo & the framework")
		return
	}
	// Cgo binary
	resetVars()
	if err := parseBuildArgs(jirix, []string{"cgo"}); err != nil {
		t.Error(err)
		return
	}
	if !buildCgo || buildFramework {
		t.Error("Should only build the cgo binary")
		return
	}
	// Cgo binary + framework
	resetVars()
	if err := parseBuildArgs(jirix, []string{"cgo", "framework"}); err != nil {
		t.Error(err)
		return
	}
	if !buildCgo || !buildFramework {
		t.Error("Should the cgo binary & framework")
		return
	}
	// Framework requires universal
	resetVars()
	flagTargetArch = targetArchAmd64
	if err := parseBuildArgs(jirix, []string{"cgo", "framework"}); err == nil {
		t.Error("Expected error building framework for 1 architecture")
		return
	}
}

func TestAllCgoBuildForArmFails(t *testing.T) {
	for _, p := range projects {
		jirix := initForTest(t)
		// Expect error for ARM currently as of Go 1.5
		if err := testCgoBuildForArch(jirix, p, targetArchArm, buildModeArchive); err == nil {
			t.Error("Expected error for building unsupported 32-bit arm")
		}
	}
}

func TestVanadiumCoreCgoBuildForArm64(t *testing.T) {
	jirix := initForTest(t)
	if err := testCgoBuildForArch(jirix, projectVanadiumCore, targetArchArm64, buildModeArchive); err != nil {
		t.Error(err)
	}
	// Currently disabled as we're not using shared libraries and the unit test can take a while.
	// Turn back on if we move to shared libraries to get around bitcode restrictions.
	//if err := testCgoBuildForArch(jirix, projectVanadiumCore, targetArchArm64, buildModeShared); err != nil {
	//	t.Error(err)
	//}
}

// We don't test amd64 as that gets tested in the universal builds below (which also tests the arm64 build but
// doesn't inspect the results as closely).

func TestSyncbaseCoreCgoBuildForArm64(t *testing.T) {
	jirix := initForTest(t)
	if err := testCgoBuildForArch(jirix, projectSyncbaseCore, targetArchArm64, buildModeArchive); err != nil {
		t.Error(err)
	}
	// Currently disabled as we're not using shared libraries and the unit test can take a while.
	// Turn back on if we move to shared libraries to get around bitcode restrictions.
	//if err := testCgoBuildForArch(jirix, projectSyncbaseCore, targetArchArm64, buildModeShared); err != nil {
	//	t.Error(err)
	//}
}

func testCgoBuildForArch(jirix *jiri.X, p *project, arch string, buildMode string) error {
	resetVars()
	buildCgo = true
	flagBuildMode = buildMode
	flagTargetArch = arch
	flagProject = p.name
	if err := parseProjectFlag(); err != nil {
		return err
	}
	if err := parseBuildFlags(); err != nil {
		return err
	}
	if err := runBuildCgo(jirix); err != nil {
		return err
	}
	if err := verifyCgoBuild(jirix); err != nil {
		return err
	}
	return nil
}

func verifyCgoBuild(jirix *jiri.X) error {
	// Verify library exists
	for _, targetArch := range targetArchs {
		binaryPath, err := cgoBinaryPath(jirix, targetArch, flagBuildMode)
		if err != nil {
			return err
		}
		if !pathExists(binaryPath) {
			return fmt.Errorf("Could not find binary at %v", binaryPath)
		} else {
			// Verify library is built for iPhone only
			if err := verifyCgoBinaryForIOS(binaryPath); err != nil {
				return err
			}
			// Verify exported symbols are present
			if err := verifyCgoBinaryExports(binaryPath); err != nil {
				return err
			}
			// Verify target architecture
			verifyCgoBinaryArchOrPanic(binaryPath, targetArch)
		}
	}
	// Verify shared header exists
	if err := verifyCgoSharedHeaders(jirix); err != nil {
		return err
	}
	// Verify generated header (simple sanity check)
	if err := verifyCgoGeneratedHeader(jirix); err != nil {
		return err
	}
	return nil
}

func cgoBinaryPath(jirix *jiri.X, arch string, buildMode string) (string, error) {
	binaryPath := path.Join(getSwiftTargetDir(jirix), fmt.Sprintf("%v_%v", selectedProject.libraryBinaryName, arch))
	switch buildMode {
	case buildModeArchive:
		binaryPath = binaryPath + ".a"
	case buildModeShared:
		binaryPath = binaryPath + ".dylib"
	default:
		return "", fmt.Errorf("Unsupported build mode %v", buildMode)
	}
	return binaryPath, nil
}

func verifyCgoBinaryForIOS(binaryPath string) error {
	stdout := sh.Cmd("otool", "-l", binaryPath).Stdout()
	if strings.Contains(stdout, "LC_VERSION_MIN_MACOSX") {
		return fmt.Errorf("Binary contains LC_VERSION_MIN_MACOSX indicating an OS-X build binary")
	}
	if !strings.Contains(stdout, "LC_VERSION_MIN_IPHONEOS") {
		return fmt.Errorf("Binary is missing LC_VERSION_MIN_IPHONEOS so it's not clear that it's built for the iOS platform")
	}
	return nil
}

// verifyCgoBinaryExports looks at the symbols in the library to look for cgo-wrapper exported functions
func verifyCgoBinaryExports(binaryPath string) error {
	stdout := sh.Cmd("otool", "-l", binaryPath).Stdout()
	// Test a couple of key functions to make sure we're getting our exports
	for _, symbol := range selectedProject.testCheckExportedSymbols {
		if !strings.Contains(stdout, symbol) {
			fmt.Errorf("Missing %v in %v export table", symbol, binaryPath)
		}
	}
	return nil
}

func verifyCgoSharedHeaders(jirix *jiri.X) error {
	goTypesPath := path.Join(getSwiftTargetDir(jirix), "go_types.h")
	if !pathExists(goTypesPath) {
		return fmt.Errorf("Missing go_types.h at %v", goTypesPath)
	}
	bytes, err := ioutil.ReadFile(goTypesPath)
	if err != nil {
		return err
	}
	goTypes := string(bytes)
	for _, typedef := range selectedProject.testCheckSharedTypes {
		if !strings.Contains(goTypes, typedef) {
			return fmt.Errorf("Missing shared typedef of %v in %v", typedef, goTypesPath)
		}
	}
	return nil
}

func verifyCgoGeneratedHeader(jirix *jiri.X) error {
	cgoExportsPath := path.Join(getSwiftTargetDir(jirix), "cgo_exports.h")
	if !pathExists(cgoExportsPath) {
		return fmt.Errorf("Missing cgo_exports.h at %v", cgoExportsPath)
	}
	bytes, err := ioutil.ReadFile(cgoExportsPath)
	if err != nil {
		return err
	}
	cgoExports := string(bytes)
	for _, symbol := range selectedProject.testCheckExportedSymbols {
		if !strings.Contains(cgoExports, symbol) {
			return fmt.Errorf("Missing symbol %v in %v", symbol, cgoExportsPath)
		}
	}
	if !strings.Contains(cgoExports, "#ifdef __LP64__") {
		return fmt.Errorf("Missing __LP64__ guard for 32/64-bit cleaness in %v", cgoExportsPath)
	}
	if strings.Count(cgoExports, "_check_for_32_bit_pointer_matching_GoInt") != 1 {
		return fmt.Errorf("32-bit check should only occur once %v", cgoExportsPath)
	}
	if strings.Count(cgoExports, "_check_for_64_bit_pointer_matching_GoInt") != 1 {
		return fmt.Errorf("64-bit check should only occur once %v", cgoExportsPath)
	}
	s, e := strings.Index(cgoExports, "/* Start of preamble"), strings.Index(cgoExports, "/* End of preamble")
	if s == -1 || e == -1 {
		return fmt.Errorf("Missing preamble section")
	}
	for _, line := range strings.Split(cgoExports[s:e], "\n") {
		switch {
		case strings.TrimSpace(line) == "":
			continue
		case strings.HasPrefix(line, " ") || strings.HasPrefix(line, "\t"):
			return fmt.Errorf("Looks like indented code in preamble")
		}
	}
	return nil
}

func TestVanadiumCoreUniversalFrameworkBuilds(t *testing.T) {
	testUniversalFrameworkBuild(t, projectVanadiumCore)
}

func TestSyncbaseCoreUniversalFrameworkBuilds(t *testing.T) {
	testUniversalFrameworkBuild(t, projectSyncbaseCore)
}

func testUniversalFrameworkBuild(t *testing.T, p *project) {
	jirix := initForTest(t)
	flagTargetArch = targetArchAll
	flagProject = p.name
	if err := parseProjectFlag(); err != nil {
		t.Error(err)
		return
	}
	if err := parseBuildFlags(); err != nil {
		t.Error(err)
		return
	}
	// Make sure VanadiumCore exports exist
	if err := runBuildCgo(jirix); err != nil {
		t.Error(err)
		return
	}
	if err := runBuildFramework(jirix); err != nil {
		t.Error(err)
		return
	}
	binaryPath := filepath.Join(flagOutDirSwift, selectedProject.frameworkName, selectedProject.frameworkBinaryName)
	if err := verifyCgoBinaryForIOS(binaryPath); err != nil {
		t.Error(err)
		return
	}
	for _, targetArch := range targetArchs {
		appleArch, _ := appleArchFromGoArch(targetArch)
		sh.Cmd("lipo", binaryPath, "-verify_arch", appleArch).Run()
		if !pathExists(filepath.Join(flagOutDirSwift, selectedProject.frameworkName, "Modules", selectedProject.frameworkBinaryName+".swiftmodule", appleArch+".swiftdoc")) {
			t.Errorf("Missing swift moduledoc for architecture %v", targetArch)
		}
		if !pathExists(filepath.Join(flagOutDirSwift, selectedProject.frameworkName, "Modules", selectedProject.frameworkBinaryName+".swiftmodule", appleArch+".swiftmodule")) {
			t.Errorf("Missing swift module for architecture %v", targetArch)
		}
	}
}
