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

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"reflect"
	"strings"
	"testing"

	"v.io/v23/naming"
	"v.io/v23/security"
	"v.io/v23/services/application"
	"v.io/v23/services/device"
	"v.io/x/lib/cmdline"
	"v.io/x/ref/lib/v23cmd"
	"v.io/x/ref/test"

	cmd_device "v.io/x/ref/services/device/device"
)

func createFile(t *testing.T, path string, contents string) {
	if err := ioutil.WriteFile(path, []byte(contents), 0700); err != nil {
		t.Fatalf("Failed to create %v: %v", path, err)
	}
}

func TestInstallLocalCommand(t *testing.T) {
	ctx, shutdown := test.V23Init()
	defer shutdown()

	tapes := newTapeMap()
	server, endpoint, err := startServer(t, ctx, tapes)
	if err != nil {
		return
	}
	defer stopServer(t, server)
	// Setup the command-line.
	cmd := cmd_device.CmdRoot
	var stdout, stderr bytes.Buffer
	env := &cmdline.Env{Stdout: &stdout, Stderr: &stderr}
	deviceName := naming.JoinAddressName(endpoint.String(), "")
	const appTitle = "Appo di tutti Appi"
	binary := os.Args[0]
	fi, err := os.Stat(binary)
	if err != nil {
		t.Fatalf("Failed to stat %v: %v", binary, err)
	}
	binarySize := fi.Size()
	rootTape := tapes.forSuffix("")
	for i, c := range []struct {
		args         []string
		stderrSubstr string
	}{
		{
			[]string{deviceName}, "incorrect number of arguments",
		},
		{
			[]string{deviceName, appTitle}, "missing binary",
		},
		{
			[]string{deviceName, appTitle, "a=b"}, "missing binary",
		},
		{
			[]string{deviceName, appTitle, "foo"}, "binary foo not found",
		},
		{
			[]string{deviceName, appTitle, binary, "PACKAGES", "foo"}, "foo not found",
		},
	} {
		c.args = append([]string{"install-local"}, c.args...)
		if err := v23cmd.ParseAndRunForTest(cmd, ctx, env, c.args); err == nil {
			t.Fatalf("test case %d: wrongly failed to receive a non-nil error.", i)
		} else {
			fmt.Fprintln(&stderr, "ERROR:", err)
			if want, got := c.stderrSubstr, stderr.String(); !strings.Contains(got, want) {
				t.Errorf("test case %d: %q not found in stderr: %q", i, want, got)
			}
		}
		if got, expected := len(rootTape.Play()), 0; got != expected {
			t.Errorf("test case %d: invalid call sequence. Got %v, want %v", i, got, expected)
		}
		rootTape.Rewind()
		stdout.Reset()
		stderr.Reset()
	}
	emptySig := security.Signature{}
	emptyBlessings := security.Blessings{}
	cfg := device.Config{"someflag": "somevalue"}

	testPackagesDir, err := ioutil.TempDir("", "testdir")
	if err != nil {
		t.Fatalf("Failed to create temp dir: %v", err)
	}
	defer os.RemoveAll(testPackagesDir)
	pkgFile1 := filepath.Join(testPackagesDir, "file1.txt")
	createFile(t, pkgFile1, "1234567")
	pkgFile2 := filepath.Join(testPackagesDir, "file2")
	createFile(t, pkgFile2, string([]byte{0x01, 0x02, 0x03, 0x04}))
	pkgDir1 := filepath.Join(testPackagesDir, "dir1")
	if err := os.Mkdir(pkgDir1, 0700); err != nil {
		t.Fatalf("Failed to create dir1: %v", err)
	}
	createFile(t, filepath.Join(pkgDir1, "f1"), "123")
	createFile(t, filepath.Join(pkgDir1, "f2"), "456")
	createFile(t, filepath.Join(pkgDir1, "f3"), "7890")

	pkgFile3 := filepath.Join(testPackagesDir, "file3")
	createFile(t, pkgFile3, "12345")
	pkgFile4 := filepath.Join(testPackagesDir, "file4")
	createFile(t, pkgFile4, "123")
	pkgDir2 := filepath.Join(testPackagesDir, "dir2")
	if err := os.Mkdir(pkgDir2, 0700); err != nil {
		t.Fatalf("Failed to create dir2: %v", err)
	}
	createFile(t, filepath.Join(pkgDir2, "f1"), "123456")
	createFile(t, filepath.Join(pkgDir2, "f2"), "78")
	pkg := application.Packages{
		"overridepkg1": application.SignedFile{File: pkgFile3},
		"overridepkg2": application.SignedFile{File: pkgFile4},
		"overridepkg3": application.SignedFile{File: pkgDir2},
	}

	for i, c := range []struct {
		args         []string
		config       device.Config
		packages     application.Packages
		expectedTape interface{}
	}{
		{
			[]string{deviceName, appTitle, binary},
			nil,
			nil,
			InstallStimulus{
				"Install",
				appNameAfterFetch,
				nil,
				nil,
				application.Envelope{
					Title: appTitle,
					Binary: application.SignedFile{
						File:      binaryNameAfterFetch,
						Signature: emptySig,
					},
					Publisher: emptyBlessings,
				},
				map[string]int64{"binary": binarySize}},
		},
		{
			[]string{deviceName, appTitle, binary},
			cfg,
			nil,
			InstallStimulus{
				"Install",
				appNameAfterFetch,
				cfg,
				nil,
				application.Envelope{
					Title: appTitle,
					Binary: application.SignedFile{
						File:      binaryNameAfterFetch,
						Signature: emptySig,
					},
					Publisher: emptyBlessings,
				},
				map[string]int64{"binary": binarySize}},
		},
		{
			[]string{deviceName, appTitle, "ENV1=V1", "ENV2=V2", binary, "FLAG1=V1", "FLAG2=V2"},
			nil,
			nil,
			InstallStimulus{
				"Install",
				appNameAfterFetch,
				nil,
				nil,
				application.Envelope{
					Title: appTitle,
					Binary: application.SignedFile{
						File:      binaryNameAfterFetch,
						Signature: emptySig,
					},
					Publisher: emptyBlessings,
					Env:       []string{"ENV1=V1", "ENV2=V2"},
					Args:      []string{"FLAG1=V1", "FLAG2=V2"},
				},
				map[string]int64{"binary": binarySize}},
		},
		{
			[]string{deviceName, appTitle, "ENV=V", binary, "FLAG=V", "PACKAGES", pkgFile1, pkgFile2, pkgDir1},
			nil,
			pkg,
			InstallStimulus{"Install",
				appNameAfterFetch,
				nil,
				nil,
				application.Envelope{
					Title: appTitle,
					Binary: application.SignedFile{
						File:      binaryNameAfterFetch,
						Signature: emptySig,
					},
					Publisher: emptyBlessings,
					Env:       []string{"ENV=V"},
					Args:      []string{"FLAG=V"},
				},
				map[string]int64{
					"binary":                        binarySize,
					"packages/file1.txt":            7,
					"packages/file2":                4,
					"packages/dir1":                 10,
					"overridepackages/overridepkg1": 5,
					"overridepackages/overridepkg2": 3,
					"overridepackages/overridepkg3": 8,
				},
			},
		},
	} {
		const appId = "myBestAppID"
		rootTape.SetResponses(InstallResponse{appId, nil})
		if c.config != nil {
			jsonConfig, err := json.Marshal(c.config)
			if err != nil {
				t.Fatalf("test case %d: Marshal(%v) failed: %v", i, c.config, err)
			}
			c.args = append([]string{fmt.Sprintf("--config=%s", string(jsonConfig))}, c.args...)
		}
		if c.packages != nil {
			jsonPackages, err := json.Marshal(c.packages)
			if err != nil {
				t.Fatalf("test case %d: Marshal(%v) failed: %v", i, c.packages, err)
			}
			c.args = append([]string{fmt.Sprintf("--packages=%s", string(jsonPackages))}, c.args...)
		}
		c.args = append([]string{"install-local"}, c.args...)
		if err := v23cmd.ParseAndRunForTest(cmd, ctx, env, c.args); err != nil {
			t.Fatalf("test case %d: %v", i, err)
		}
		if expected, got := naming.Join(deviceName, appId), strings.TrimSpace(stdout.String()); got != expected {
			t.Fatalf("test case %d: Unexpected output from Install. Got %q, expected %q", i, got, expected)
		}
		if got, expected := rootTape.Play(), []interface{}{c.expectedTape}; !reflect.DeepEqual(expected, got) {
			t.Errorf("test case %d: Invalid call sequence. Got %#v, want %#v", i, got, expected)
		}
		rootTape.Rewind()
		stdout.Reset()
		stderr.Reset()
	}
}
