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

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/security"

	"v.io/x/lib/cmdline"
	"v.io/x/lib/vlog"
)

func isValidLockName(lockName string) bool {
	// TODO(ataly): HACK!! We should either store the set of valid names
	// in a file that is managed by this client or somehow note in the
	// blessing store whether a peer pattern is the name of a lock object.
	return lockName != string(security.AllPrincipals) && !strings.ContainsAny(lockName, security.ChainSeparator)
}

func isKeyValidForLock(ctx *context.T, key security.Blessings, lockName string) bool {
	bp := security.BlessingPattern(lockName + security.ChainSeparator + "key")
	for b, _ := range v23.GetPrincipal(ctx).BlessingsInfo(key) {
		if bp.MatchedBy(b) {
			return true
		}
	}
	return false
}

func keyForLock(ctx *context.T, lockName string) (security.Blessings, error) {
	// We could simply return  v23.GetPrincipal(ctx).BlessingStore().ForPeer(lock)
	// however this would also include any blessings tagged for a peer pattern
	// is matched by 'lock'. Therefore we iterate over all the blessings
	// and pick the specific ones that are meant for 'lock'.
	var ret security.Blessings
	for _, b := range v23.GetPrincipal(ctx).BlessingStore().PeerBlessings() {
		if isKeyValidForLock(ctx, b, lockName) {
			if union, err := security.UnionOfBlessings(ret, b); err != nil {
				vlog.Errorf("UnionOfBlessings(%v, %v) failed: %v, dropping latter blessing", ret, b, err)
			} else {
				ret = union
			}
		}
	}
	if ret.IsZero() {
		return security.Blessings{}, fmt.Errorf("no available key for lock %v", lockName)
	}
	return ret, nil
}

func saveKeyForLock(ctx *context.T, key security.Blessings, lockName string) error {
	if isKeyValidForLock(ctx, key, lockName) {
		return fmt.Errorf("key %v is not valid for lock %v", key, lockName)
	}
	p := v23.GetPrincipal(ctx)
	if _, err := p.BlessingStore().Set(key, security.BlessingPattern(lockName)); err != nil {
		return fmt.Errorf("failed to save key %v for lock %v", key, lockName)
	}
	if err := p.AddToRoots(key); err != nil {
		return fmt.Errorf("failed to save key %v for lock %v", key, lockName)
	}
	return nil
}

func readFromStdin(env *cmdline.Env, prompt string) (string, error) {
	fmt.Fprintf(env.Stdout, "%v ", prompt)
	os.Stdout.Sync()
	// Cannot use bufio because that may "lose" data beyond the line (the
	// remainder in the buffer).
	// Do the inefficient byte-by-byte scan for now - shouldn't be a problem
	// given the common use case. If that becomes a problem, switch to bufio
	// and share the bufio.Reader between multiple calls to readFromStdin.
	buf := make([]byte, 0, 100)
	r := make([]byte, 1)
	for {
		n, err := env.Stdin.Read(r)
		if n == 1 && r[0] == '\n' {
			break
		}
		if n == 1 {
			buf = append(buf, r[0])
			continue
		}
		if err != nil {
			return "", err
		}
	}
	return strings.TrimSpace(string(buf)), nil
}
