// 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"
	"math/rand"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/naming"
	"v.io/v23/security"
	"v.io/x/lib/vlog"
	"v.io/x/lock/locklib"
)

var unclaimedLockNhSuffix = "unclaimed-lock-" + fmt.Sprintf("%d", rand.Intn(1000000))

// startServer checks whether the lock has been claimed and then appropriately
// starts the server.
//
// Returns the callback to be invoked to shutdown the server on success, or
// an error on failure
func startServer(ctx *context.T, configDir string) (func(), error) {
	// The lock is claimed if and only if there exists a file in the
	// config directory from a previous claim.
	if isLockClaimed(configDir) {
		return startLockServer(ctx, configDir)
	}

	claimed, stopUnclaimedLock, err := startUnclaimedLockServer(ctx, configDir)
	if err != nil {
		return nil, err
	}

	stop := make(chan struct{})
	stopped := make(chan struct{})
	go waitToBeClaimedAndStartLockServer(ctx, configDir, stopUnclaimedLock, claimed, stop, stopped)
	return func() {
		close(stop)
		<-stopped
	}, nil
}

func startUnclaimedLockServer(ctx *context.T, configDir string) (<-chan struct{}, func(), error) {
	// Start a local mounttable where the unclaimed lock server would
	// be mounted, and make this mounttable visible in the local
	// neighborhood.
	mtName, stopMT, err := locklib.StartMounttable(ctx, configDir, locklib.LockNhPrefix+unclaimedLockNhSuffix)
	if err != nil {
		return nil, nil, err
	}
	ctx, _, err = v23.WithNewNamespace(ctx, mtName)
	if err != nil {
		stopMT()
		return nil, nil, err
	}
	claimed := make(chan struct{})
	ctx, cancel := context.WithCancel(ctx)
	_, server, err := v23.WithNewServer(ctx, lockObjectName(ctx), newUnclaimedLock(claimed, configDir), security.AllowEveryone())
	if err != nil {
		stopMT()
		return nil, nil, err
	}
	stopUnclaimedLock := func() {
		cancel()
		vlog.Infof("Stopping unclaimed lock server...")
		<-server.Closed()
		vlog.Infof("Stopped unclaimed lock server...")
		stopMT()
	}
	vlog.Infof("Started unclaimed lock server\n")
	vlog.Infof("ENDPOINT: %v\n", server.Status().Endpoints[0].Name())
	return claimed, stopUnclaimedLock, nil
}

func startLockServer(ctx *context.T, configDir string) (func(), error) {
	blessings, _ := v23.GetPrincipal(ctx).BlessingStore().Default()
	lockNhSuffix := fmt.Sprint(blessings)
	// Start a local mounttable where the lock server would be
	// mounted, and make this mounttable visible in the local
	// neighborhood.
	mtName, stopMT, err := locklib.StartMounttable(ctx, configDir, locklib.LockNhPrefix+lockNhSuffix)
	if err != nil {
		return nil, err
	}
	ctx, _, err = v23.WithNewNamespace(ctx, mtName)
	if err != nil {
		stopMT()
		return nil, err
	}
	ctx, cancel := context.WithCancel(ctx)
	_, server, err := v23.WithNewServer(ctx, lockObjectName(ctx), newLock(), security.DefaultAuthorizer())
	if err != nil {
		stopMT()
		return nil, err
	}
	stopLock := func() {
		cancel()
		vlog.Infof("Stopping lock server...")
		<-server.Closed()
		vlog.Infof("Stopped lock server...")
		stopMT()
	}
	vlog.Infof("Started lock server\n")
	vlog.Infof("ENDPOINT: %v\n", server.Status().Endpoints[0].Name())
	return stopLock, nil
}

func waitToBeClaimedAndStartLockServer(ctx *context.T, configDir string, stopUnclaimedLock func(), claimed, stop <-chan struct{}, stopped chan<- struct{}) {
	defer close(stopped)
	select {
	case <-claimed:
		stopUnclaimedLock()
	case <-stop:
		stopUnclaimedLock()
		return
	}
	stopLock, err := startLockServer(ctx, configDir)
	if err != nil {
		vlog.Errorf("Failed to start lock server after it was claimed: %v", err)
		return
	}
	defer stopLock()
	<-stop // Wait to be stopped
}

func lockObjectName(ctx *context.T) string {
	nsroots := v23.GetNamespace(ctx).Roots()
	if len(nsroots) == 0 {
		return ""
	}
	return naming.Join(nsroots[0], locklib.LockSuffix)
}
