package impl

import (
	"crypto/md5"
	"encoding/hex"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/ipc"
	"v.io/v23/naming"
	"v.io/v23/security"
	"v.io/v23/services/mgmt/application"
	"v.io/v23/services/mgmt/binary"
	"v.io/v23/services/mgmt/device"
	"v.io/v23/services/mgmt/repository"
	"v.io/v23/services/security/access"
	"v.io/v23/uniqueid"
	"v.io/v23/vlog"

	pkglib "v.io/core/veyron/services/mgmt/lib/packages"
	"v.io/x/lib/cmdline"
)

var cmdInstallLocal = &cmdline.Command{
	Run:      runInstallLocal,
	Name:     "install-local",
	Short:    "Install the given application from the local system.",
	Long:     "Install the given application, specified using a local path.",
	ArgsName: "<device> <title> [ENV=VAL ...] binary [--flag=val ...] [PACKAGES path ...]",
	ArgsLong: `
<device> is the veyron object name of the device manager's app service.

<title> is the app title.

This is followed by an arbitrary number of environment variable settings, the
local path for the binary to install, and arbitrary flag settings and args.
Optionally, this can be followed by 'PACKAGES' and a list of local files and
directories to be installed as packages for the app`}

func init() {
	cmdInstallLocal.Flags.Var(&configOverride, "config", "JSON-encoded device.Config object, of the form: '{\"flag1\":\"value1\",\"flag2\":\"value2\"}'")
	cmdInstallLocal.Flags.Var(&packagesOverride, "packages", "JSON-encoded application.Packages object, of the form: '{\"pkg1\":{\"File\":\"local file path1\"},\"pkg2\":{\"File\":\"local file path 2\"}}'")
}

type openAuthorizer struct{}

func (openAuthorizer) Authorize(security.Context) error { return nil }

type mapDispatcher map[string]interface{}

func (d mapDispatcher) Lookup(suffix string) (interface{}, security.Authorizer, error) {
	o, ok := d[suffix]
	if !ok {
		return nil, nil, fmt.Errorf("suffix %s not found", suffix)
	}
	// TODO(caprita): Do not open authorizer even for a short-lived server.
	return o, &openAuthorizer{}, nil
}

type mapServer struct {
	name       string
	dispatcher mapDispatcher
}

func (ms *mapServer) serve(name string, object interface{}) (string, error) {
	if _, ok := ms.dispatcher[name]; ok {
		return "", fmt.Errorf("can't have more than one object with name %v", name)
	}
	ms.dispatcher[name] = object
	return naming.Join(ms.name, name), nil
}

func createServer(ctx *context.T, stderr io.Writer) (*mapServer, func(), error) {
	server, err := v23.NewServer(ctx)
	if err != nil {
		return nil, nil, err
	}
	spec := v23.GetListenSpec(ctx)
	endpoints, err := server.Listen(spec)
	if err != nil {
		return nil, nil, err
	}
	var name string
	if spec.Proxy != "" {
		id, err := uniqueid.Random()
		if err != nil {
			return nil, nil, err
		}
		name = id.String()
	}
	dispatcher := make(mapDispatcher)
	if err := server.ServeDispatcher(name, dispatcher); err != nil {
		return nil, nil, err
	}
	vlog.VI(1).Infof("Server listening on %v (%v)", endpoints, name)
	cleanup := func() {
		if err := server.Stop(); err != nil {
			fmt.Fprintf(stderr, "server.Stop failed: %v", err)
		}
	}
	if name != "" {
		// Send a name rooted in our namespace root rather than the
		// relative name (in case the device manager uses a different
		// namespace root).
		//
		// TODO(caprita): Avoid relying on a mounttable altogether, and
		// instead pull out the proxied address and just send that.
		nsRoots := v23.GetNamespace(ctx).Roots()
		if len(nsRoots) > 0 {
			name = naming.Join(nsRoots[0], name)
		}
	} else if len(endpoints) > 0 {
		name = endpoints[0].Name()
	} else {
		return nil, nil, fmt.Errorf("no endpoints")
	}
	return &mapServer{name: name, dispatcher: dispatcher}, cleanup, nil
}

var errNotImplemented = fmt.Errorf("method not implemented")

type binaryInvoker string

func (binaryInvoker) Create(ipc.ServerContext, int32, repository.MediaInfo) error {
	return errNotImplemented
}

func (binaryInvoker) Delete(ipc.ServerContext) error {
	return errNotImplemented
}

func (i binaryInvoker) Download(ctx repository.BinaryDownloadContext, _ int32) error {
	fileName := string(i)
	file, err := os.Open(fileName)
	if err != nil {
		return err
	}
	defer file.Close()
	bufferLength := 4096
	buffer := make([]byte, bufferLength)
	sender := ctx.SendStream()
	for {
		n, err := file.Read(buffer)
		switch err {
		case io.EOF:
			return nil
		case nil:
			if err := sender.Send(buffer[:n]); err != nil {
				return err
			}
		default:
			return err
		}
	}
}

func (binaryInvoker) DownloadURL(ipc.ServerContext) (string, int64, error) {
	return "", 0, errNotImplemented
}

func (i binaryInvoker) Stat(ctx ipc.ServerContext) ([]binary.PartInfo, repository.MediaInfo, error) {
	fileName := string(i)
	h := md5.New()
	bytes, err := ioutil.ReadFile(fileName)
	if err != nil {
		return []binary.PartInfo{}, repository.MediaInfo{}, err
	}
	h.Write(bytes)
	part := binary.PartInfo{Checksum: hex.EncodeToString(h.Sum(nil)), Size: int64(len(bytes))}
	return []binary.PartInfo{part}, pkglib.MediaInfoForFileName(fileName), nil
}

func (binaryInvoker) Upload(repository.BinaryUploadContext, int32) error {
	return errNotImplemented
}

func (binaryInvoker) GetACL(ctx ipc.ServerContext) (acl access.TaggedACLMap, etag string, err error) {
	return nil, "", errNotImplemented
}

func (binaryInvoker) SetACL(ctx ipc.ServerContext, acl access.TaggedACLMap, etag string) error {
	return errNotImplemented
}

type envelopeInvoker application.Envelope

func (i envelopeInvoker) Match(ipc.ServerContext, []string) (application.Envelope, error) {
	return application.Envelope(i), nil
}
func (envelopeInvoker) GetACL(ipc.ServerContext) (acl access.TaggedACLMap, etag string, err error) {
	return nil, "", errNotImplemented
}

func (envelopeInvoker) SetACL(ipc.ServerContext, access.TaggedACLMap, string) error {
	return errNotImplemented
}

func servePackage(p string, ms *mapServer, tmpZipDir string) (string, string, error) {
	info, err := os.Stat(p)
	if os.IsNotExist(err) {
		return "", "", fmt.Errorf("%v not found: %v", p, err)
	} else if err != nil {
		return "", "", fmt.Errorf("Stat(%v) failed: %v", p, err)
	}
	pkgName := naming.Join("packages", info.Name())
	fileName := p
	// Directory packages first get zip'ped.
	if info.IsDir() {
		fileName = filepath.Join(tmpZipDir, info.Name()+".zip")
		if err := pkglib.CreateZip(fileName, p); err != nil {
			return "", "", err
		}
	}
	name, err := ms.serve(pkgName, repository.BinaryServer(binaryInvoker(fileName)))
	return info.Name(), name, err
}

// runInstallLocal creates a new envelope on the fly from the provided
// arguments, and then points the device manager back to itself for downloading
// the app envelope and binary.
//
// It sets up an app and binary server that only lives for the duration of the
// command, and listens on the profile's listen spec.  The caller should set the
// --veyron.proxy if the machine running the command is not accessible from the
// device manager.
//
// TODO(caprita/ashankar): We should use bi-directional streams to get this
// working over the same connection that the command makes to the device
// manager.
func runInstallLocal(cmd *cmdline.Command, args []string) error {
	if expectedMin, got := 2, len(args); got < expectedMin {
		return cmd.UsageErrorf("install-local: incorrect number of arguments, expected at least %d, got %d", expectedMin, got)
	}
	deviceName, title := args[0], args[1]
	args = args[2:]
	envelope := application.Envelope{Title: title}
	// Extract the environment settings, binary, and arguments.
	firstNonEnv := len(args)
	for i, arg := range args {
		if strings.Index(arg, "=") <= 0 {
			firstNonEnv = i
			break
		}
	}
	envelope.Env = args[:firstNonEnv]
	args = args[firstNonEnv:]
	if len(args) == 0 {
		return cmd.UsageErrorf("install-local: missing binary")
	}
	binary := args[0]
	args = args[1:]
	firstNonArg, firstPackage := len(args), len(args)
	for i, arg := range args {
		if arg == "PACKAGES" {
			firstNonArg = i
			firstPackage = i + 1
			break
		}
	}
	envelope.Args = args[:firstNonArg]
	pkgs := args[firstPackage:]
	if _, err := os.Stat(binary); err != nil {
		return fmt.Errorf("binary %v not found: %v", binary, err)
	}
	server, cancel, err := createServer(gctx, cmd.Stderr())
	if err != nil {
		return fmt.Errorf("failed to create server: %v", err)
	}
	defer cancel()
	envelope.Binary.File, err = server.serve("binary", repository.BinaryServer(binaryInvoker(binary)))
	if err != nil {
		return err
	}

	// For each package dir/file specified in the arguments list, set up an
	// object in the binary service to serve that package, and add the
	// object name to the envelope's Packages map.
	tmpZipDir, err := ioutil.TempDir("", "packages")
	if err != nil {
		return fmt.Errorf("failed to create a temp dir for zip packages: %v", err)
	}
	defer os.RemoveAll(tmpZipDir)
	for _, p := range pkgs {
		if envelope.Packages == nil {
			envelope.Packages = make(application.Packages)
		}
		pname, oname, err := servePackage(p, server, tmpZipDir)
		if err != nil {
			return err
		}
		vlog.VI(1).Infof("package %v serving as %v", pname, oname)
		envelope.Packages[pname] = application.SignedFile{File: oname}
	}
	packagesRewritten := application.Packages{}
	for pname, pspec := range packagesOverride {
		_, oname, err := servePackage(pspec.File, server, tmpZipDir)
		if err != nil {
			return err
		}
		vlog.VI(1).Infof("package %v serving as %v", pname, oname)
		pspec.File = oname
		packagesRewritten[pname] = pspec
	}
	appName, err := server.serve("application", repository.ApplicationServer(envelopeInvoker(envelope)))
	if err != nil {
		return err
	}
	vlog.VI(1).Infof("application serving envelope as %v", appName)
	appID, err := device.ApplicationClient(deviceName).Install(gctx, appName, device.Config(configOverride), packagesRewritten)
	// Reset the value for any future invocations of "install" or
	// "install-local" (we run more than one command per process in unit
	// tests).
	configOverride = configFlag{}
	packagesOverride = packagesFlag{}
	if err != nil {
		return fmt.Errorf("Install failed: %v", err)
	}
	fmt.Fprintf(cmd.Stdout(), "Successfully installed: %q\n", naming.Join(deviceName, appID))
	return nil
}
