// Copyright 2016 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.

// The following enables go generate to generate the doc.go file.
//go:generate go run $JIRI_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help

package main

import (
	"flag"
	"os"
	"strings"
	"time"

	"v.io/v23/context"

	"v.io/x/lib/cmdline"
	"v.io/x/ref/lib/signals"
	"v.io/x/ref/lib/v23cmd"
	_ "v.io/x/ref/runtime/factories/roaming"

	"messenger/internal"
)

const defaultEncryptionKey = "This is not secure!!!"

var (
	cmdRoot = &cmdline.Command{
		Name:  "vmsg",
		Short: "Runs the vanadium messenger service",
		Long:  "Runs the vanadium messenger service.",
		Children: []*cmdline.Command{
			cmdNode, cmdChat, cmdRobot,
		},
	}
	cmdNode = &cmdline.Command{
		Runner: v23cmd.RunnerFunc(runNode),
		Name:   "node",
		Short:  "Run the standalone node",
		Long:   "Run the standalone node.",
	}

	advertisementId   string
	enableLocalDisc   bool
	globalDiscPaths   string
	storeDir          string
	maxActivePeers    int
	maxHops           int
	rateAclInJson     string
	rateAclOutJson    string
	rateAclSenderJson string
	encryptionKey     string

	incomingDir      string
	compressionLevel int
)

func main() {
	if f := flag.Lookup("alsologtostderr"); f != nil {
		f.Value.Set("false")
	}
	if f := flag.Lookup("stderrthreshold"); f != nil {
		f.Value.Set("FATAL")
	}
	cmdRoot.Flags.StringVar(&advertisementId, "advertisement-id", "", "The advertisement ID to use. If left empty, a random one is generated.")
	cmdRoot.Flags.BoolVar(&enableLocalDisc, "enable-local-discovery", true, "Whether local discovery, i.e. using mDNS and/or BLE, should be enabled.")
	cmdRoot.Flags.StringVar(&globalDiscPaths, "global-discovery-paths", "", "A comma-separated list of namespace paths to use for global discovery.")
	cmdRoot.Flags.StringVar(&storeDir, "store-dir", "", "The name of the local directory where to store the messages.")
	cmdRoot.Flags.IntVar(&maxActivePeers, "max-active-peers", 2, "The maximum number of peers to send updates to concurrently.")
	cmdRoot.Flags.IntVar(&maxHops, "max-hops", 50, "The maximum number of hops that a message can go through.")
	cmdRoot.Flags.StringVar(&rateAclInJson, "rate-acl-in", `[{"acl":{"In":["dev.v.io"]},"limit":20}]`, "The RateAcl to authorize incoming RPCs, in JSON format")
	cmdRoot.Flags.StringVar(&rateAclOutJson, "rate-acl-out", `[{"acl":{"In":["dev.v.io"]},"limit":100}]`, "The RateAcl to authorize outgoing RPCs, in JSON format")
	cmdRoot.Flags.StringVar(&rateAclSenderJson, "rate-acl-sender", `[{"acl":{"In":["dev.v.io"]},"limit":100}]`, "The RateAcl to authorize the sender of incoming messages, in JSON format")
	cmdRoot.Flags.StringVar(&encryptionKey, "encryption-key", defaultEncryptionKey, "Messages are encrypted with AES256 using this key")

	cmdChat.Flags.StringVar(&incomingDir, "incoming-dir", os.TempDir(), "The directory where to save incoming files")
	cmdChat.Flags.IntVar(&compressionLevel, "compression-level", -1, "The gzip compression level for the message content. A value of -1 means default compressions; 1 is best speed; 9 is best compression.")

	cmdline.HideGlobalFlagsExcept()
	cmdline.Main(cmdRoot)
}

func paramsFromFlags(ctx *context.T, env *cmdline.Env) (params internal.Params, err error) {
	if storeDir == "" {
		err = env.UsageErrorf("--store-dir must be set")
		return
	}
	var paths []string
	if globalDiscPaths != "" {
		paths = strings.Split(globalDiscPaths, ",")
	}

	params.AdvertisementID = advertisementId
	params.EnableLocalDiscovery = enableLocalDisc
	params.GlobalDiscoveryPaths = paths
	params.MaxActivePeers = maxActivePeers
	params.MaxHops = maxHops
	params.MountTTL = 20 * time.Second
	params.ScanInterval = 10 * time.Second
	params.Store = internal.NewFileStorage(ctx, storeDir)

	if params.RateAclIn, err = internal.RateAclFromJSON([]byte(rateAclInJson)); err != nil {
		return
	}
	if params.RateAclOut, err = internal.RateAclFromJSON([]byte(rateAclOutJson)); err != nil {
		return
	}
	if params.RateAclSender, err = internal.RateAclFromJSON([]byte(rateAclSenderJson)); err != nil {
		return
	}
	return
}

func runNode(ctx *context.T, env *cmdline.Env, args []string) error {
	params, err := paramsFromFlags(ctx, env)
	if err != nil {
		return err
	}
	node, err := internal.StartNode(ctx, params)
	if err != nil {
		return err
	}
	defer node.Stop()
	ctx.Infof("Listening on: %v", node.Server().Status().Endpoints)
	<-signals.ShutdownOnSignals(ctx)
	return nil
}
