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

// TODO(caprita): Rename to update_revert_test.go

import (
	"bytes"
	"fmt"
	"reflect"
	"strings"
	"testing"
	"time"
	"unicode"
	"unicode/utf8"

	"v.io/v23"
	"v.io/v23/naming"
	"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"
	"v.io/x/ref/services/internal/servicetest"
)

func capitalize(s string) string {
	r, size := utf8.DecodeRuneInString(s)
	if r == utf8.RuneError {
		return ""
	}
	return string(unicode.ToUpper(r)) + s[size:]
}

// TestUpdateAndRevertCommands verifies the device update and revert commands.
func TestUpdateAndRevertCommands(t *testing.T) {
	ctx, shutdown := test.V23Init()
	defer shutdown()
	tapes := servicetest.NewTapeMap()
	ctx, server, err := v23.WithNewDispatchingServer(ctx, "", newDispatcher(t, tapes))
	if err != nil {
		t.Fatalf("NewServer failed: %v", err)
	}
	addr := server.Status().Endpoints[0].String()
	root := cmd_device.CmdRoot
	appName := naming.JoinAddressName(addr, "app")
	rootTape := tapes.ForSuffix("")
	globName := naming.JoinAddressName(addr, "glob")
	// TODO(caprita): Move joinLines to a common place.
	joinLines := func(args ...string) string {
		return strings.Join(args, "\n")
	}
	for _, cmd := range []string{"update", "revert"} {
		for _, c := range []struct {
			globResponses   []string
			statusResponses map[string][]interface{}
			expectedStimuli map[string][]interface{}
			expectedStdout  string
			expectedStderr  string
			expectedError   string
		}{
			{ // Everything succeeds.
				[]string{"app/2", "app/1", "app/5", "app/3", "app/4"},
				map[string][]interface{}{
					"app/1": []interface{}{instanceRunning, nil, nil, nil},
					"app/2": []interface{}{instanceNotRunning, nil},
					"app/3": []interface{}{installationActive, nil},
					// The uninstalled installation and the
					// deleted instance should be excluded
					// from the Update and Revert as per the
					// default GlobSettings for the update
					// and revert commands.
					"app/4": []interface{}{installationUninstalled, nil},
					"app/5": []interface{}{instanceDeleted, nil},
				},
				map[string][]interface{}{
					"app/1": []interface{}{"Status", KillStimulus{"Kill", 10 * time.Second}, capitalize(cmd), "Run"},
					"app/2": []interface{}{"Status", capitalize(cmd)},
					"app/3": []interface{}{"Status", capitalize(cmd)},
				},
				joinLines(
					fmt.Sprintf("Successful %s of version for installation \"%s/3\".", cmd, appName),
					fmt.Sprintf("Successful %s of version for instance \"%s/1\".", cmd, appName),
					fmt.Sprintf("Successful %s of version for instance \"%s/2\".", cmd, appName)),
				"",
				"",
			},
			{ // Assorted failure modes.
				[]string{"app/1", "app/2", "app/3", "app/4", "app/5"},
				map[string][]interface{}{
					// Starts as running, fails Kill, but then
					// recovers. This ultimately counts as a success.
					"app/1": []interface{}{instanceRunning, fmt.Errorf("Simulate Kill failing"), instanceNotRunning, nil, nil},
					// Starts as running, fails Kill, and stays running.
					"app/2": []interface{}{instanceRunning, fmt.Errorf("Simulate Kill failing"), instanceRunning},
					// Starts as running, Kill and Update succeed, but Run fails.
					"app/3": []interface{}{instanceRunning, nil, nil, fmt.Errorf("Simulate Run failing")},
					// Starts as running, Kill succeeds, Update fails, but Run succeeds.
					"app/4": []interface{}{instanceRunning, nil, fmt.Errorf("Simulate %s failing", capitalize(cmd)), nil},
					// Starts as running, Kill succeeds, Update fails, and Run fails.
					"app/5": []interface{}{instanceRunning, nil, fmt.Errorf("Simulate %s failing", capitalize(cmd)), fmt.Errorf("Simulate Run failing")},
				},
				map[string][]interface{}{
					"app/1": []interface{}{"Status", KillStimulus{"Kill", 10 * time.Second}, "Status", capitalize(cmd), "Run"},
					"app/2": []interface{}{"Status", KillStimulus{"Kill", 10 * time.Second}, "Status"},
					"app/3": []interface{}{"Status", KillStimulus{"Kill", 10 * time.Second}, capitalize(cmd), "Run"},
					"app/4": []interface{}{"Status", KillStimulus{"Kill", 10 * time.Second}, capitalize(cmd), "Run"},
					"app/5": []interface{}{"Status", KillStimulus{"Kill", 10 * time.Second}, capitalize(cmd), "Run"},
				},
				joinLines(
					fmt.Sprintf("Successful %s of version for instance \"%s/1\".", cmd, appName),
					fmt.Sprintf("Successful %s of version for instance \"%s/3\".", cmd, appName),
				),
				joinLines(
					fmt.Sprintf("WARNING for \"%s/1\": recovered from Kill error (device.test:<rpc.Client>\"%s/1\".Kill: Error: Simulate Kill failing). Proceeding with %s.", appName, appName, cmd),
					fmt.Sprintf("ERROR for \"%s/2\": Kill failed: device.test:<rpc.Client>\"%s/2\".Kill: Error: Simulate Kill failing.", appName, appName),
					fmt.Sprintf("ERROR for \"%s/3\": Run failed: device.test:<rpc.Client>\"%s/3\".Run: Error: Simulate Run failing.", appName, appName),
					fmt.Sprintf("ERROR for \"%s/4\": %s failed: device.test:<rpc.Client>\"%s/4\".%s: Error: Simulate %s failing.", appName, capitalize(cmd), appName, capitalize(cmd), capitalize(cmd)),
					fmt.Sprintf("ERROR for \"%s/5\": Run failed: device.test:<rpc.Client>\"%s/5\".Run: Error: Simulate Run failing.", appName, appName),
					fmt.Sprintf("ERROR for \"%s/5\": %s failed: device.test:<rpc.Client>\"%s/5\".%s: Error: Simulate %s failing.", appName, capitalize(cmd), appName, capitalize(cmd), capitalize(cmd)),
				),
				"encountered a total of 4 error(s)",
			},
		} {
			var stdout, stderr bytes.Buffer
			env := &cmdline.Env{Stdout: &stdout, Stderr: &stderr}
			tapes.Rewind()
			rootTape.SetResponses(GlobResponse{results: c.globResponses})
			for n, r := range c.statusResponses {
				tapes.ForSuffix(n).SetResponses(r...)
			}
			args := []string{cmd, globName}
			if err := v23cmd.ParseAndRunForTest(root, ctx, env, args); err != nil {
				if want, got := c.expectedError, err.Error(); want != got {
					t.Errorf("Unexpected error: want %v, got %v", want, got)
				}
			} else {
				if c.expectedError != "" {
					t.Errorf("Expected to get error %v, but didn't get any error.", c.expectedError)
				}
			}

			if expected, got := c.expectedStdout, strings.TrimSpace(stdout.String()); got != expected {
				t.Errorf("Unexpected stdout output from %s.\nGot:\n%v\nExpected:\n%v", cmd, got, expected)
			}
			if expected, got := c.expectedStderr, strings.TrimSpace(stderr.String()); got != expected {
				t.Errorf("Unexpected stderr output from %s.\nGot:\n%v\nExpected:\n%v", cmd, got, expected)
			}
			for n, m := range c.expectedStimuli {
				if want, got := m, tapes.ForSuffix(n).Play(); !reflect.DeepEqual(want, got) {
					t.Errorf("Unexpected stimuli for %v. Want: %v, got %v.", n, want, got)
				}
			}
			cmd_device.ResetGlobSettings()
		}
	}
}
