// 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 (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"testing"
	"time"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/naming"
	"v.io/v23/rpc"
	"v.io/v23/security"
	"v.io/v23/security/access"
	"v.io/v23/services/application"
	"v.io/v23/services/binary"
	"v.io/v23/services/device"
	"v.io/v23/services/repository"
	"v.io/x/lib/vlog"

	"v.io/x/ref/services/internal/binarylib"
	"v.io/x/ref/services/internal/packages"
)

type mockDeviceInvoker struct {
	tape *tape
	t    *testing.T
}

// Mock ListAssociations
type ListAssociationResponse struct {
	na  []device.Association
	err error
}

func (mdi *mockDeviceInvoker) ListAssociations(*context.T, rpc.ServerCall) (associations []device.Association, err error) {
	vlog.VI(2).Infof("ListAssociations() was called")

	ir := mdi.tape.Record("ListAssociations")
	r := ir.(ListAssociationResponse)
	return r.na, r.err
}

// Mock AssociateAccount
type AddAssociationStimulus struct {
	fun           string
	identityNames []string
	accountName   string
}

// simpleCore implements the core of all mock methods that take
// arguments and return error.
func (mdi *mockDeviceInvoker) simpleCore(callRecord interface{}, name string) error {
	ri := mdi.tape.Record(callRecord)
	switch r := ri.(type) {
	case nil:
		return nil
	case error:
		return r
	}
	log.Fatalf("%s (mock) response %v is of bad type", name, ri)
	return nil
}

func (mdi *mockDeviceInvoker) AssociateAccount(_ *context.T, _ rpc.ServerCall, identityNames []string, accountName string) error {
	return mdi.simpleCore(AddAssociationStimulus{"AssociateAccount", identityNames, accountName}, "AssociateAccount")
}

func (mdi *mockDeviceInvoker) Claim(_ *context.T, _ rpc.ServerCall, pairingToken string) error {
	return mdi.simpleCore("Claim", "Claim")
}

func (*mockDeviceInvoker) Describe(*context.T, rpc.ServerCall) (device.Description, error) {
	return device.Description{}, nil
}

func (*mockDeviceInvoker) IsRunnable(_ *context.T, _ rpc.ServerCall, description binary.Description) (bool, error) {
	return false, nil
}

func (*mockDeviceInvoker) Reset(_ *context.T, _ rpc.ServerCall, deadline uint64) error { return nil }

// Mock Install
type InstallStimulus struct {
	fun      string
	appName  string
	config   device.Config
	packages application.Packages
	envelope application.Envelope
	// files holds a map from file  or package name to file or package size.
	// The app binary  has the key "binary". Each of  the packages will have
	// the key "package/<package name>". The override packages will have the
	// key "overridepackage/<package name>".
	files map[string]int64
}

type InstallResponse struct {
	appId string
	err   error
}

const (
	// If provided with this app name, the mock device manager skips trying
	// to fetch the envelope from the name.
	appNameNoFetch = "skip-envelope-fetching"
	// If provided with a fetcheable app name, the mock device manager sets
	// the app name in the stimulus to this constant.
	appNameAfterFetch = "envelope-fetched"
	// The mock device manager sets the binary name in the envelope in the
	// stimulus to this constant.
	binaryNameAfterFetch = "binary-fetched"
)

func packageSize(pkgPath string) int64 {
	info, err := os.Stat(pkgPath)
	if err != nil {
		return -1
	}
	if info.IsDir() {
		infos, err := ioutil.ReadDir(pkgPath)
		if err != nil {
			return -1
		}
		var size int64
		for _, i := range infos {
			size += i.Size()
		}
		return size
	} else {
		return info.Size()
	}
}

func fetchPackageSize(ctx *context.T, pkgVON string) (int64, error) {
	dir, err := ioutil.TempDir("", "package")
	if err != nil {
		return 0, fmt.Errorf("failed to create temp package dir: %v", err)
	}
	defer os.RemoveAll(dir)
	tmpFile := filepath.Join(dir, "downloaded")
	if err := binarylib.DownloadToFile(ctx, pkgVON, tmpFile); err != nil {
		return 0, fmt.Errorf("DownloadToFile failed: %v", err)
	}
	dst := filepath.Join(dir, "install")
	if err := packages.Install(tmpFile, dst); err != nil {
		return 0, fmt.Errorf("packages.Install failed: %v", err)
	}
	return packageSize(dst), nil
}

func (mdi *mockDeviceInvoker) Install(ctx *context.T, _ rpc.ServerCall, appName string, config device.Config, packages application.Packages) (string, error) {
	is := InstallStimulus{"Install", appName, config, packages, application.Envelope{}, nil}
	if appName != appNameNoFetch {
		// Fetch the envelope and record it in the stimulus.
		envelope, err := repository.ApplicationClient(appName).Match(ctx, []string{"test"})
		if err != nil {
			return "", err
		}
		binaryName := envelope.Binary.File
		envelope.Binary.File = binaryNameAfterFetch
		is.appName = appNameAfterFetch
		is.files = make(map[string]int64)
		// Fetch the binary and record its size in the stimulus.
		data, mediaInfo, err := binarylib.Download(ctx, binaryName)
		if err != nil {
			return "", err
		}
		is.files["binary"] = int64(len(data))
		if mediaInfo.Type != "application/octet-stream" {
			return "", fmt.Errorf("unexpected media type: %v", mediaInfo)
		}
		// Iterate over the packages, download them, compute the size of
		// the file(s) that make up each package, and record that in the
		// stimulus.
		for pkgLocalName, pkgVON := range envelope.Packages {
			size, err := fetchPackageSize(ctx, pkgVON.File)
			if err != nil {
				return "", err
			}
			is.files[naming.Join("packages", pkgLocalName)] = size
		}
		envelope.Packages = nil
		for pkgLocalName, pkg := range packages {
			size, err := fetchPackageSize(ctx, pkg.File)
			if err != nil {
				return "", err
			}
			is.files[naming.Join("overridepackages", pkgLocalName)] = size
		}
		is.packages = nil
		is.envelope = envelope
	}
	r := mdi.tape.Record(is).(InstallResponse)
	return r.appId, r.err
}

func (mdi *mockDeviceInvoker) Run(*context.T, rpc.ServerCall) error {
	return mdi.simpleCore("Run", "Run")
}

func (i *mockDeviceInvoker) Revert(*context.T, rpc.ServerCall) error { return nil }

type InstantiateResponse struct {
	err        error
	instanceID string
}

func (mdi *mockDeviceInvoker) Instantiate(*context.T, rpc.StreamServerCall) (string, error) {
	ir := mdi.tape.Record("Instantiate")
	r := ir.(InstantiateResponse)
	return r.instanceID, r.err
}

type KillStimulus struct {
	fun   string
	delta time.Duration
}

func (mdi *mockDeviceInvoker) Kill(_ *context.T, _ rpc.ServerCall, delta time.Duration) error {
	return mdi.simpleCore(KillStimulus{"Kill", delta}, "Kill")
}

func (mdi *mockDeviceInvoker) Delete(*context.T, rpc.ServerCall) error {
	return mdi.simpleCore("Delete", "Delete")
}

func (*mockDeviceInvoker) Uninstall(*context.T, rpc.ServerCall) error { return nil }

func (mdi *mockDeviceInvoker) Update(*context.T, rpc.ServerCall) error {
	return mdi.simpleCore("Update", "Update")
}

func (*mockDeviceInvoker) UpdateTo(*context.T, rpc.ServerCall, string) error { return nil }

// Mock Permissions getting and setting
type GetPermissionsResponse struct {
	perms   access.Permissions
	version string
	err     error
}

type SetPermissionsStimulus struct {
	fun     string
	perms   access.Permissions
	version string
}

func (mdi *mockDeviceInvoker) SetPermissions(_ *context.T, _ rpc.ServerCall, perms access.Permissions, version string) error {
	return mdi.simpleCore(SetPermissionsStimulus{"SetPermissions", perms, version}, "SetPermissions")
}

func (mdi *mockDeviceInvoker) GetPermissions(*context.T, rpc.ServerCall) (access.Permissions, string, error) {
	ir := mdi.tape.Record("GetPermissions")
	r := ir.(GetPermissionsResponse)
	return r.perms, r.version, r.err
}

func (mdi *mockDeviceInvoker) Debug(*context.T, rpc.ServerCall) (string, error) {
	ir := mdi.tape.Record("Debug")
	r := ir.(string)
	return r, nil
}

func (mdi *mockDeviceInvoker) Status(*context.T, rpc.ServerCall) (device.Status, error) {
	ir := mdi.tape.Record("Status")
	r := ir.(device.Status)
	return r, nil
}

type GlobStimulus struct {
	pattern string
}

type GlobResponse struct {
	results []string
}

func (mdi *mockDeviceInvoker) Glob__(_ *context.T, _ rpc.ServerCall, pattern string) (<-chan naming.GlobReply, error) {
	gs := GlobStimulus{pattern}
	gr := mdi.tape.Record(gs).(GlobResponse)
	ch := make(chan naming.GlobReply, len(gr.results))
	defer close(ch)
	for _, r := range gr.results {
		ch <- naming.GlobReplyEntry{naming.MountEntry{Name: r}}
	}
	return ch, nil
}

type dispatcher struct {
	tapes *tapeMap
	t     *testing.T
}

func newDispatcher(t *testing.T, tapes *tapeMap) rpc.Dispatcher {
	return &dispatcher{tapes: tapes, t: t}
}

func (d *dispatcher) Lookup(suffix string) (interface{}, security.Authorizer, error) {
	return &mockDeviceInvoker{tape: d.tapes.forSuffix(suffix), t: d.t}, nil, nil
}

func startServer(t *testing.T, ctx *context.T, tapes *tapeMap) (rpc.Server, naming.Endpoint, error) {
	dispatcher := newDispatcher(t, tapes)
	server, err := v23.NewServer(ctx)
	if err != nil {
		t.Errorf("NewServer failed: %v", err)
		return nil, nil, err
	}
	endpoints, err := server.Listen(v23.GetListenSpec(ctx))
	if err != nil {
		t.Errorf("Listen failed: %v", err)
		stopServer(t, server)
		return nil, nil, err
	}
	if err := server.ServeDispatcher("", dispatcher); err != nil {
		t.Errorf("ServeDispatcher failed: %v", err)
		stopServer(t, server)
		return nil, nil, err
	}
	return server, endpoints[0], nil
}

func stopServer(t *testing.T, server rpc.Server) {
	if err := server.Stop(); err != nil {
		t.Errorf("server.Stop failed: %v", err)
	}
}
