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

import (
	"encoding/base64"
	"time"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/rpc"
	"v.io/v23/security"
	"v.io/v23/verror"
	"v.io/v23/vom"

	"v.io/x/ref/lib/exec"
	"v.io/x/ref/lib/mgmt"
	vsecurity "v.io/x/ref/lib/security"
)

const pkgPath = "v.io/x/ref/option/internal/rt"

var (
	errConfigKeyNotSet = verror.Register(pkgPath+".errConfigKeyNotSet", verror.NoRetry, "{1:}{2:} {3} is not set{:_}")
)

func (rt *Runtime) initMgmt(ctx *context.T) error {
	handle, err := exec.GetChildHandle()
	if err == nil {
		// No error; fall through.
	} else if verror.ErrorID(err) == exec.ErrNoVersion.ID {
		// Do not initialize the mgmt runtime if the process has not
		// been started through the vanadium exec library by a device
		// manager.
		return nil
	} else {
		return err
	}
	parentName, err := handle.Config.Get(mgmt.ParentNameConfigKey)
	if err != nil {
		// If the ParentNameConfigKey is not set, then this process has
		// not been started by the device manager, but the parent process
		// is still a Vanadium process using the exec library so we
		// call SetReady to let it know that this child process has
		// successfully started.
		return handle.SetReady()
	}
	if ctx, err = setListenSpec(ctx, rt, handle); err != nil {
		return err
	}
	var blessings security.Blessings
	if b64blessings, err := handle.Config.Get(mgmt.AppCycleBlessingsKey); err == nil {
		vombytes, err := base64.URLEncoding.DecodeString(b64blessings)
		if err == nil {
			err = vom.Decode(vombytes, &blessings)
		}
		if err != nil {
			return err
		}
	} else {
		// TODO(caprita,ashankar): This case should only happen when
		// the device manager starts itself up as a child process for
		// testing (see services/device/deviced/internal/impl/device_service.go,
		// specifically testDeviceManager function).
		// FIx that up so it is no longer the case?
		blessings = rt.GetPrincipal(ctx).BlessingStore().Default()
	}
	// Arguably could use the same principal with a different blessing store
	// and blessing roots. However, at the time of this writing there wasn't
	// a particularly convenient way to do so, and this alternative scheme
	// works just as well.
	//
	// Instantiate a principal that will be used by the AppCycleManager
	// which will communicate with (both as a client and a server) only the
	// device manager.
	principal, err := vsecurity.NewPrincipal()
	if err != nil {
		return err
	}
	blessings, err = rt.GetPrincipal(ctx).Bless(principal.PublicKey(), blessings, "instance", security.UnconstrainedUse())
	if err != nil {
		return err
	}
	if err := security.AddToRoots(principal, blessings); err != nil {
		return err
	}
	if err := principal.BlessingStore().SetDefault(blessings); err != nil {
		return err
	}
	if _, err := principal.BlessingStore().Set(blessings, security.AllPrincipals); err != nil {
		return err
	}
	if ctx, err = rt.WithPrincipal(ctx, principal); err != nil {
		return err
	}
	// Fire up the server to receive calls from the parent and also ping the parent.
	_, server, err := rt.WithNewServer(ctx, "", v23.GetAppCycle(ctx).Remote(), nil)
	if err != nil {
		return err
	}
	if err = rt.callbackToParent(ctx, parentName, server.Status().Endpoints[0].Name()); err != nil {
		server.Stop()
		return err
	}
	return handle.SetReady()
}

func setListenSpec(ctx *context.T, rt *Runtime, handle *exec.ChildHandle) (*context.T, error) {
	protocol, err := handle.Config.Get(mgmt.ProtocolConfigKey)
	if err != nil {
		return nil, err
	}
	if protocol == "" {
		return nil, verror.New(errConfigKeyNotSet, ctx, mgmt.ProtocolConfigKey)
	}

	address, err := handle.Config.Get(mgmt.AddressConfigKey)
	if err != nil {
		return nil, err
	}
	if address == "" {
		return nil, verror.New(errConfigKeyNotSet, ctx, mgmt.AddressConfigKey)
	}
	return rt.WithListenSpec(ctx, rpc.ListenSpec{Addrs: rpc.ListenAddrs{{protocol, address}}}), nil
}

func (rt *Runtime) callbackToParent(ctx *context.T, parentName, myName string) error {
	ctx, _ = context.WithTimeout(ctx, time.Minute)
	return rt.GetClient(ctx).Call(ctx, parentName, "Set", []interface{}{mgmt.AppCycleManagerConfigKey, myName}, nil)
}
