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

import (
	"fmt"
	"os"
	"path/filepath"
	"regexp"
	"runtime"
	"strings"
	"time"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/naming"
	"v.io/v23/security"
	"v.io/v23/security/access"
	"v.io/v23/services/application"
	"v.io/v23/services/permissions"
	"v.io/v23/verror"
	"v.io/x/lib/cmdline"
	"v.io/x/ref/lib/v23cmd"
	"v.io/x/ref/services/internal/binarylib"
	"v.io/x/ref/services/repository"
)

// TODO(caprita): Add unit test.

// TODO(caprita): Extend to include env, args, packages.

var cmdPublish = &cmdline.Command{
	Runner: v23cmd.RunnerFunc(runPublish),
	Name:   "publish",
	Short:  "Publish the given application(s).",
	Long: `
Publishes the given application(s) to the binary and application servers.
The binaries should be in $V23_ROOT/release/go/bin/[<GOOS>_<GOARCH>] by default (can be overrriden with --from).
By default the binary name is used as the name of the application envelope, and as the
title in the envelope. However, <envelope-name> and <title> can be specified explicitly
using :<envelope-name> and @<title>.
The binary is published as <binserv>/<binary name>/<GOOS>-<GOARCH>/<TIMESTAMP>.
The application envelope is published as <appserv>/<envelope-name>/0.
Optionally, adds blessing patterns to the Read and Resolve AccessLists.`,
	ArgsName: "<binary name>[:<envelope-name>][@<title>] ...",
}

var binaryService, applicationService, readBlessings, goarchFlag, goosFlag, fromFlag string
var addPublisher bool
var minValidPublisherDuration time.Duration

func init() {
	cmdPublish.Flags.StringVar(&binaryService, "binserv", "binaries", "Name of binary service.")
	cmdPublish.Flags.StringVar(&applicationService, "appserv", "applications", "Name of application service.")
	cmdPublish.Flags.StringVar(&goosFlag, "goos", runtime.GOOS, "GOOS for application.  The default is the value of runtime.GOOS.")
	cmdPublish.Flags.Lookup("goos").DefValue = "<runtime.GOOS>"
	cmdPublish.Flags.StringVar(&goarchFlag, "goarch", runtime.GOARCH, "GOARCH for application.  The default is the value of runtime.GOARCH.")
	cmdPublish.Flags.Lookup("goarch").DefValue = "<runtime.GOARCH>"
	cmdPublish.Flags.StringVar(&readBlessings, "readers", "dev.v.io", "If non-empty, comma-separated blessing patterns to add to Read and Resolve AccessList.")
	cmdPublish.Flags.BoolVar(&addPublisher, "add-publisher", true, "If true, add a publisher blessing to the application envelope")
	cmdPublish.Flags.DurationVar(&minValidPublisherDuration, "publisher-min-validity", 30*time.Hour, "Publisher blessings that are valid for less than this amount of time are considered invalid")
	cmdPublish.Flags.StringVar(&fromFlag, "from", "", "Location of binaries to be published.  Defaults to $V23_ROOT/release/go/bin/[<GOOS>_<GOARCH>]")
}

func setAccessLists(ctx *context.T, env *cmdline.Env, von string) error {
	if readBlessings == "" {
		return nil
	}
	perms, version, err := permissions.ObjectClient(von).GetPermissions(ctx)
	if err != nil {
		// TODO(caprita): This is a workaround until we sort out the
		// default AccessLists for applicationd (see issue #1317).  At that
		// time, uncomment the line below.
		//
		//   return err
		perms = make(access.Permissions)
	}
	for _, blessing := range strings.Split(readBlessings, ",") {
		for _, tag := range []access.Tag{access.Read, access.Resolve} {
			perms.Add(security.BlessingPattern(blessing), string(tag))
		}
	}
	if err := permissions.ObjectClient(von).SetPermissions(ctx, perms, version); err != nil {
		return err
	}
	fmt.Fprintf(env.Stdout, "Added patterns %q to Read,Resolve AccessList for %q\n", readBlessings, von)
	return nil
}

func publishOne(ctx *context.T, env *cmdline.Env, binPath, binary string) error {
	binaryName, envelopeName, title := binary, binary, binary
	binaryRE := regexp.MustCompile(`^([^:@]+)(:[^@]+)?(@.+)?$`)
	if parts := binaryRE.FindStringSubmatch(binary); len(parts) == 4 {
		binaryName = parts[1]
		envelopeName, title = binaryName, binaryName
		if len(parts[2]) > 1 {
			envelopeName = parts[2][1:]
		}
		if len(parts[3]) > 1 {
			title = parts[3][1:]
		}
	} else {
		return fmt.Errorf("invalid binary spec (%v)", binary)
	}

	// Step 1, upload the binary to the binary service.

	// TODO(caprita): Instead of the current timestamp, use each binary's
	// BuildTimestamp from the buildinfo.
	timestamp := time.Now().UTC().Format(time.RFC3339)
	binaryVON := naming.Join(binaryService, binaryName, fmt.Sprintf("%s-%s", goosFlag, goarchFlag), timestamp)
	binaryFile := filepath.Join(binPath, binaryName)
	binarySig, err := binarylib.UploadFromFile(ctx, binaryVON, binaryFile)
	if err != nil {
		return err
	}
	fmt.Fprintf(env.Stdout, "Binary %q uploaded from file %s\n", binaryVON, binaryFile)

	// Step 2, set the perms for the uploaded binary.

	if err := setAccessLists(ctx, env, binaryVON); err != nil {
		return err
	}

	// Step 3, download existing envelope (or create a new one), update, and
	// upload to application service.

	// TODO(caprita): use the profile detection machinery and/or let user
	// specify profiles by hand.
	profiles := []string{fmt.Sprintf("%s-%s", goosFlag, goarchFlag)}
	// TODO(caprita): use a label e.g. "prod" instead of "0".
	appVON := naming.Join(applicationService, envelopeName, "0")
	appClient := repository.ApplicationClient(appVON)
	// NOTE: If profiles contains more than one entry, this will return only
	// the first match.  But presumably that's ok, since we're going to set
	// the envelopes for all the profiles to the same envelope anyway below.
	envelope, err := appClient.Match(ctx, profiles)
	if verror.ErrorID(err) == verror.ErrNoExist.ID {
		// There was nothing published yet, create a new envelope.
		envelope = application.Envelope{Title: title}
	} else if err != nil {
		return err
	} else {
		// We are going to be updating an existing envelope

		// Complain if a title was specified explicitly and does not match the one in the
		// envelope, because we are not going to update the one in the envelope
		if title != binaryName && title != envelope.Title {
			return fmt.Errorf("Specified title (%v) does not match title in existing envelope (%v)", title, envelope.Title)
		}
	}

	envelope.Binary.File = binaryVON
	if addPublisher {
		publisher, err := getPublisherBlessing(ctx, "apps/published/"+title)
		if err != nil {
			return err
		}
		envelope.Publisher = publisher
		envelope.Binary.Signature = *binarySig
	} else {
		// We must explicitly clear these fields because we might be trying to update
		// an envelope that previously pointed at a signed binary.
		envelope.Binary.Signature = security.Signature{}
		envelope.Publisher = security.Blessings{}
	}

	if err := repository.ApplicationClient(appVON).Put(ctx, profiles, envelope); err != nil {
		return err
	}
	fmt.Fprintf(env.Stdout, "Published %q\n", appVON)

	// Step 4, set the perms for the uploaded envelope.

	if err := setAccessLists(ctx, env, appVON); err != nil {
		return err
	}
	return nil
}

func runPublish(ctx *context.T, env *cmdline.Env, args []string) error {
	if expectedMin, got := 1, len(args); got < expectedMin {
		return env.UsageErrorf("publish: incorrect number of arguments, expected at least %d, got %d", expectedMin, got)
	}
	binaries := args
	binPath := fromFlag
	if binPath == "" {
		vroot := env.Vars["V23_ROOT"]
		if vroot == "" {
			return env.UsageErrorf("publish: $V23_ROOT environment variable should be set")
		}
		binPath = filepath.Join(vroot, "release/go/bin")
		if goosFlag != runtime.GOOS || goarchFlag != runtime.GOARCH {
			binPath = filepath.Join(binPath, fmt.Sprintf("%s_%s", goosFlag, goarchFlag))
		}
	}
	if fi, err := os.Stat(binPath); err != nil {
		return env.UsageErrorf("publish: failed to stat %v: %v", binPath, err)
	} else if !fi.IsDir() {
		return env.UsageErrorf("publish: %v is not a directory", binPath)
	}
	if binaryService == "" {
		return env.UsageErrorf("publish: --binserv must point to a binary service name")
	}
	if applicationService == "" {
		return env.UsageErrorf("publish: --appserv must point to an application service name")
	}
	var lastErr error
	for _, b := range binaries {
		if err := publishOne(ctx, env, binPath, b); err != nil {
			fmt.Fprintf(env.Stderr, "Failed to publish %q: %v\n", b, err)
			lastErr = err
		}
	}
	return lastErr
}

func getPublisherBlessing(ctx *context.T, extension string) (security.Blessings, error) {
	p := v23.GetPrincipal(ctx)
	b, err := p.Bless(p.PublicKey(), p.BlessingStore().Default(), extension, security.UnconstrainedUse())

	if err != nil {
		return security.Blessings{}, err
	}

	// We need to make sure that the blessing is usable as a publisher blessing -- in
	// practice this current means that it has no caveats other than expiration. We
	// test this by putting it into a call object and verifying that the blessing will
	// not be rejected
	call := security.NewCall(&security.CallParams{
		RemoteBlessings: b,
		LocalBlessings:  p.BlessingStore().Default(),
		LocalPrincipal:  p,
		Timestamp:       time.Now().Add(minValidPublisherDuration),
	})
	accepted, rejected := security.RemoteBlessingNames(ctx, call)
	if len(accepted) == 0 {
		return security.Blessings{}, fmt.Errorf("All blessings are invalid: %v", rejected)
	}
	if len(rejected) > 0 {
		fmt.Fprintf(os.Stderr, "Warning: Some invalid blessings are present: %v", rejected)
	}
	return b, nil
}
