// 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"
	"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())
	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 := principal.AddToRoots(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})
}
