// 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 (
	"fmt"
	"os"
	"os/user"
	"strconv"
	"syscall"

	"v.io/v23/context"
	"v.io/v23/naming"
	"v.io/v23/security"
	"v.io/v23/verror"
	"v.io/x/ref/envvar"
	"v.io/x/ref/lib/exec"
	"v.io/x/ref/lib/mgmt"
	vsecurity "v.io/x/ref/lib/security"
	inaming "v.io/x/ref/profiles/internal/naming"
	"v.io/x/ref/services/agent/agentlib"
)

func (r *Runtime) initPrincipal(ctx *context.T, credentials string) (principal security.Principal, deps []interface{}, err error) {
	if principal, _ = ctx.Value(principalKey).(security.Principal); principal != nil {
		return principal, nil, nil
	}
	if len(credentials) > 0 {
		// Explicitly specified credentials, ignore the agent.
		if _, fd, _ := agentEP(); fd >= 0 {
			syscall.Close(fd)
		}
		// TODO(ataly, ashankar): If multiple runtimes are getting
		// initialized at the same time from the same
		// envvar.Credentials we will need some kind of locking for the
		// credential files.
		if principal, err = vsecurity.LoadPersistentPrincipal(credentials, nil); err != nil {
			if os.IsNotExist(err) {
				if principal, err = vsecurity.CreatePersistentPrincipal(credentials, nil); err != nil {
					return principal, nil, err
				}
				return principal, nil, vsecurity.InitDefaultBlessings(principal, defaultBlessingName())
			}
			return nil, nil, err
		}
		return principal, nil, nil
	}
	// Use credentials stored in the agent.
	if ep, _, err := agentEP(); err != nil {
		return nil, nil, err
	} else if ep != nil {
		// Use a new stream manager and an "incomplete" client (the
		// principal is nil) to talk to the agent.
		//
		// The lack of a principal works out for the rpc.Client
		// only because the agent uses anonymous unix sockets and
		// the SecurityNone option.
		//
		// Using a distinct stream manager to manage agent-related
		// connections helps isolate these connections to the agent
		// from management of any other connections created in the
		// process (such as future RPCs to other services).
		if ctx, err = r.WithNewStreamManager(ctx); err != nil {
			return nil, nil, err
		}
		client := r.GetClient(ctx)
		if principal, err = agentlib.NewAgentPrincipal(ctx, ep, client); err != nil {
			client.Close()
			return nil, nil, err
		}
		return principal, []interface{}{client}, nil
	}
	// No agent, no explicit credentials specified: - create a new principal and blessing in memory.
	if principal, err = vsecurity.NewPrincipal(); err != nil {
		return principal, nil, err
	}
	return principal, nil, vsecurity.InitDefaultBlessings(principal, defaultBlessingName())
}

func parseAgentFD(ep naming.Endpoint) (int, error) {
	fd := ep.Addr().String()
	ifd, err := strconv.Atoi(fd)
	if err != nil {
		ifd = -1
	}
	return ifd, nil
}

// agentEP returns an Endpoint to be used to communicate with
// the security agent if the current process has been configured to use the
// agent.
func agentEP() (naming.Endpoint, int, error) {
	handle, err := exec.GetChildHandle()
	if err != nil && verror.ErrorID(err) != exec.ErrNoVersion.ID {
		return nil, -1, err
	}
	var endpoint string
	if handle != nil {
		// We were started by a parent (presumably, device manager).
		endpoint, _ = handle.Config.Get(mgmt.SecurityAgentEndpointConfigKey)
	} else {
		endpoint = os.Getenv(envvar.AgentEndpoint)
	}
	if endpoint == "" {
		return nil, -1, nil
	}
	ep, err := inaming.NewEndpoint(endpoint)
	if err != nil {
		return nil, -1, err
	}

	// Don't let children accidentally inherit the agent connection.
	fd, err := parseAgentFD(ep)
	if err != nil {
		return nil, -1, err
	}
	if fd >= 0 {
		syscall.CloseOnExec(fd)
	}
	return ep, fd, nil
}

func defaultBlessingName() string {
	var name string
	if user, _ := user.Current(); user != nil && len(user.Username) > 0 {
		name = user.Username
	} else {
		name = "anonymous"
	}
	if host, _ := os.Hostname(); len(host) > 0 {
		name = name + "@" + host
	}
	return fmt.Sprintf("%s-%d", name, os.Getpid())
}
