// 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 (
	"os"
	"path/filepath"
	"strings"
	"sync"

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

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

const (
	claimFileName        = "claimed_lock"
	keyBlessingExtension = "key"
)

type unclaimedLock struct {
	configDir string
	claimed   chan<- struct{} // GUARDED_BY(mu)

	// Mutex to ensure that a successful claim can happen at most once.
	mu sync.Mutex
}

func (ul *unclaimedLock) Claim(ctx *context.T, call rpc.ServerCall, name string) (security.Blessings, error) {
	vlog.Infof("Claim called by %q", call.Security().RemoteBlessings())
	if strings.ContainsAny(name, security.ChainSeparator) {
		// TODO(ataly, ashankar): We have to error out in this case because of the current
		// neighborhood setup wherein the neighborhood-name of a claimed lock's mounttable is
		// the same as the locks's name. Since neighborhood-names aren't allowed to contain
		// slashes, we have to disallow slashes in the lock name as well.
		return security.Blessings{}, NewErrInvalidLockName(ctx, name, security.ChainSeparator)
	}

	var (
		principal      = v23.GetPrincipal(ctx)
		origDefault, _ = principal.BlessingStore().Default()
		restore        = func() error {
			// TODO(ataly): Remove roots of current default blessing if needed
			// (i.e., if current default != origDefault).
			if err := principal.BlessingStore().SetDefault(origDefault); err != nil {
				return verror.Convert(verror.ErrInternal, ctx, err)
			}
			return nil
		}
	)

	defer ul.mu.Unlock()
	ul.mu.Lock()

	if ul.claimed == nil {
		return security.Blessings{}, NewErrLockAlreadyClaimed(ctx)
	}

	keyBlessing, err := ul.makeKey(principal, name, call.Security().RemoteBlessings().PublicKey())
	if err != nil {
		restore()
		return security.Blessings{}, verror.Convert(verror.ErrInternal, ctx, err)
	}

	// Create a file in the config directory to indicate that lock has been claimed.
	f, err := os.Create(filepath.Join(ul.configDir, claimFileName))
	if err != nil {
		restore()
		return security.Blessings{}, verror.Convert(verror.ErrInternal, ctx, err)
	}
	f.Close()

	close(ul.claimed)
	ul.claimed = nil
	vlog.Infof("Lock successfullly claimed with name %q", name)
	return keyBlessing, nil
}

func (ul *unclaimedLock) makeKey(principal security.Principal, name string, remoteKey security.PublicKey) (security.Blessings, error) {
	lockBlessing, err := principal.BlessSelf(name)
	if err != nil {
		return security.Blessings{}, err
	}

	if err := principal.BlessingStore().SetDefault(lockBlessing); err != nil {
		return security.Blessings{}, err
	}
	if err := security.AddToRoots(principal, lockBlessing); err != nil {
		return security.Blessings{}, err
	}

	// Add a caveat to the "key" blessing so that it can only be used to talking
	// to this lock object.
	// TODO(ataly): Add a client-only caveat as well so that someone who obtains
	// this blessing or an extension of it cannot maliciously (or accidentally)
	// start a server with this blessing (such a server could impersonate this
	// lock object).
	peerPattern := security.BlessingPattern(name)
	onlyThisLockCav, err := security.NewCaveat(security.PeerBlessingsCaveat, []security.BlessingPattern{peerPattern})
	if err != nil {
		return security.Blessings{}, err
	}
	keyBlessing, err := principal.Bless(remoteKey, lockBlessing, keyBlessingExtension, onlyThisLockCav)
	if err != nil {
		return security.Blessings{}, err
	}
	return keyBlessing, nil
}

func isLockClaimed(configDir string) bool {
	if _, err := os.Stat(filepath.Join(configDir, claimFileName)); err == nil {
		return true
	}
	return false
}

func newUnclaimedLock(claimed chan<- struct{}, configDir string) lock.UnclaimedLockServerStub {
	return lock.UnclaimedLockServer(&unclaimedLock{configDir: configDir, claimed: claimed})
}
