// 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 impl

import (
	"fmt"
	"os"
	"path"
	"path/filepath"
	"strings"
	"sync"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/naming"
	"v.io/v23/rpc"
	"v.io/v23/security"
	"v.io/v23/security/access"
	"v.io/v23/services/device"
	"v.io/v23/services/pprof"
	"v.io/v23/services/stats"
	"v.io/v23/vdl"
	"v.io/v23/vdlroot/signature"
	"v.io/v23/verror"
	"v.io/x/lib/vlog"
	"v.io/x/ref"
	"v.io/x/ref/services/agent/keymgr"
	s_device "v.io/x/ref/services/device"
	"v.io/x/ref/services/device/internal/config"
	"v.io/x/ref/services/internal/logreaderlib"
	"v.io/x/ref/services/internal/pathperms"
)

// internalState wraps state shared between different device manager
// invocations.
type internalState struct {
	callback       *callbackState
	updating       *updatingState
	securityAgent  *securityAgentState
	restartHandler func()
	testMode       bool
	// reap is the app process monitoring subsystem.
	reap *reaper
}

// dispatcher holds the state of the device manager dispatcher.
type dispatcher struct {
	// internal holds the state that persists across RPC method invocations.
	internal *internalState
	// config holds the device manager's (immutable) configuration state.
	config *config.State
	// dispatcherMutex is a lock for coordinating concurrent access to some
	// dispatcher methods.
	mu sync.RWMutex
	// TODO(rjkroege): Consider moving this inside internal.
	uat        BlessingSystemAssociationStore
	permsStore *pathperms.PathStore
	// Namespace
	mtAddress string // The address of the local mounttable.
}

var _ rpc.Dispatcher = (*dispatcher)(nil)

const (
	appsSuffix   = "apps"
	deviceSuffix = "device"
	configSuffix = "cfg"

	pkgPath = "v.io/x/ref/services/device/internal/impl"
)

var (
	ErrInvalidSuffix        = verror.Register(pkgPath+".InvalidSuffix", verror.NoRetry, "{1:}{2:} invalid suffix{:_}")
	ErrOperationFailed      = verror.Register(pkgPath+".OperationFailed", verror.NoRetry, "{1:}{2:} operation failed{:_}")
	ErrOperationInProgress  = verror.Register(pkgPath+".OperationInProgress", verror.NoRetry, "{1:}{2:} operation in progress{:_}")
	ErrAppTitleMismatch     = verror.Register(pkgPath+".AppTitleMismatch", verror.NoRetry, "{1:}{2:} app title mismatch{:_}")
	ErrUpdateNoOp           = verror.Register(pkgPath+".UpdateNoOp", verror.NoRetry, "{1:}{2:} update is no op{:_}")
	ErrInvalidOperation     = verror.Register(pkgPath+".InvalidOperation", verror.NoRetry, "{1:}{2:} invalid operation{:_}")
	ErrInvalidBlessing      = verror.Register(pkgPath+".InvalidBlessing", verror.NoRetry, "{1:}{2:} invalid blessing{:_}")
	ErrInvalidPairingToken  = verror.Register(pkgPath+".InvalidPairingToken", verror.NoRetry, "{1:}{2:} pairing token mismatch{:_}")
	ErrUnclaimedDevice      = verror.Register(pkgPath+".UnclaimedDevice", verror.NoRetry, "{1:}{2:} device needs to be claimed first")
	ErrDeviceAlreadyClaimed = verror.Register(pkgPath+".AlreadyClaimed", verror.NoRetry, "{1:}{2:} device has already been claimed")

	errInvalidConfig          = verror.Register(pkgPath+".errInvalidConfig", verror.NoRetry, "{1:}{2:} invalid config {3}{:_}")
	errCantCreateAccountStore = verror.Register(pkgPath+".errCantCreateAccountStore", verror.NoRetry, "{1:}{2:} cannot create persistent store for identity to system account associations{:_}")
	errCantCreateAppWatcher   = verror.Register(pkgPath+".errCantCreateAppWatcher", verror.NoRetry, "{1:}{2:} cannot create app status watcher{:_}")
	errNewAgentFailed         = verror.Register(pkgPath+".errNewAgentFailed", verror.NoRetry, "{1:}{2:} NewAgent() failed{:_}")
)

// NewClaimableDispatcher returns an rpc.Dispatcher that allows the device to
// be Claimed if it hasn't been already and a channel that will be closed once
// the device has been claimed.
//
// It returns (nil, nil) if the device is no longer claimable.
func NewClaimableDispatcher(ctx *context.T, config *config.State, pairingToken string) (rpc.Dispatcher, <-chan struct{}) {
	var (
		permsDir   = PermsDir(config)
		permsStore = pathperms.NewPathStore(v23.GetPrincipal(ctx))
	)
	if _, _, err := permsStore.Get(permsDir); !os.IsNotExist(err) {
		return nil, nil
	}
	// The device is claimable only if Claim hasn't been called before. The
	// existence of the Permissions file is an indication of a successful prior
	// call to Claim.
	notify := make(chan struct{})
	return &claimable{token: pairingToken, permsStore: permsStore, permsDir: permsDir, notify: notify}, notify
}

// NewDispatcher is the device manager dispatcher factory.
func NewDispatcher(ctx *context.T, config *config.State, mtAddress string, testMode bool, restartHandler func(), permStore *pathperms.PathStore) (rpc.Dispatcher, error) {
	if err := config.Validate(); err != nil {
		return nil, verror.New(errInvalidConfig, ctx, config, err)
	}
	uat, err := NewBlessingSystemAssociationStore(config.Root)
	if err != nil {
		return nil, verror.New(errCantCreateAccountStore, ctx, err)
	}
	initSuidHelper(config.Helper)
	d := &dispatcher{
		internal: &internalState{
			callback:       newCallbackState(config.Name),
			updating:       newUpdatingState(),
			restartHandler: restartHandler,
			testMode:       testMode,
		},
		config:     config,
		uat:        uat,
		permsStore: permStore,
		mtAddress:  mtAddress,
	}

	// If we're in 'security agent mode', set up the key manager agent.
	if len(os.Getenv(ref.EnvAgentEndpoint)) > 0 {
		if keyMgrAgent, err := keymgr.NewAgent(); err != nil {
			return nil, verror.New(errNewAgentFailed, ctx, err)
		} else {
			d.internal.securityAgent = &securityAgentState{
				keyMgrAgent: keyMgrAgent,
			}
		}
	}
	reap, err := newReaper(ctx, config.Root, &appRunner{
		callback:      d.internal.callback,
		securityAgent: d.internal.securityAgent,
	})
	if err != nil {
		return nil, verror.New(errCantCreateAppWatcher, ctx, err)
	}
	d.internal.reap = reap

	if testMode {
		return &testModeDispatcher{d}, nil
	}
	return d, nil
}

// Shutdown the dispatcher.
func Shutdown(rpcd rpc.Dispatcher) {
	switch d := rpcd.(type) {
	case *dispatcher:
		d.internal.reap.shutdown()
	case *testModeDispatcher:
		Shutdown(d.realDispatcher)
	default:
		vlog.Panicf("%v not a supported dispatcher type.", rpcd)
	}
}

// Logging invoker that logs any error messages before returning.
func newLoggingInvoker(obj interface{}) (rpc.Invoker, error) {
	if invoker, ok := obj.(rpc.Invoker); ok {
		return &loggingInvoker{invoker}, nil
	}
	invoker, err := rpc.ReflectInvoker(obj)
	if err != nil {
		vlog.Errorf("rpc.ReflectInvoker returned error: %v", err)
		return nil, err
	}
	return &loggingInvoker{invoker}, nil
}

type loggingInvoker struct {
	invoker rpc.Invoker
}

func (l *loggingInvoker) Prepare(method string, numArgs int) (argptrs []interface{}, tags []*vdl.Value, err error) {
	argptrs, tags, err = l.invoker.Prepare(method, numArgs)
	if err != nil {
		vlog.Errorf("Prepare(%s %d) returned error: %v", method, numArgs, err)
	}
	return
}

func (l *loggingInvoker) Invoke(ctx *context.T, call rpc.StreamServerCall, method string, argptrs []interface{}) (results []interface{}, err error) {
	results, err = l.invoker.Invoke(ctx, call, method, argptrs)
	if err != nil {
		vlog.Errorf("Invoke(method:%s argptrs:%v) returned error: %v", method, argptrs, err)
	}
	return
}

func (l *loggingInvoker) Signature(ctx *context.T, call rpc.ServerCall) ([]signature.Interface, error) {
	sig, err := l.invoker.Signature(ctx, call)
	if err != nil {
		vlog.Errorf("Signature returned error: %v", err)
	}
	return sig, err
}

func (l *loggingInvoker) MethodSignature(ctx *context.T, call rpc.ServerCall, method string) (signature.Method, error) {
	methodSig, err := l.invoker.MethodSignature(ctx, call, method)
	if err != nil {
		vlog.Errorf("MethodSignature(%s) returned error: %v", method, err)
	}
	return methodSig, err
}

func (l *loggingInvoker) Globber() *rpc.GlobState {
	return l.invoker.Globber()
}

// DISPATCHER INTERFACE IMPLEMENTATION
func (d *dispatcher) Lookup(suffix string) (interface{}, security.Authorizer, error) {
	invoker, auth, err := d.internalLookup(suffix)
	if err != nil {
		return nil, nil, err
	}
	loggingInvoker, err := newLoggingInvoker(invoker)
	if err != nil {
		return nil, nil, err
	}
	return loggingInvoker, auth, nil
}

func newTestableHierarchicalAuth(testMode bool, rootDir, childDir string, get pathperms.PermsGetter) (security.Authorizer, error) {
	if testMode {
		// In test mode, the device manager will not be able to read the
		// Permissions, because they were signed with the key of the real device
		// manager. It's not a problem because the testModeDispatcher overrides the
		// authorizer anyway.
		return nil, nil
	}
	return pathperms.NewHierarchicalAuthorizer(rootDir, childDir, get)
}

func (d *dispatcher) internalLookup(suffix string) (interface{}, security.Authorizer, error) {
	components := strings.Split(suffix, "/")
	for i := 0; i < len(components); i++ {
		if len(components[i]) == 0 {
			components = append(components[:i], components[i+1:]...)
			i--
		}
	}

	// TODO(rjkroege): Permit the root Permissions to diverge for the device and
	// app sub-namespaces of the device manager after claiming.
	auth, err := newTestableHierarchicalAuth(d.internal.testMode, PermsDir(d.config), PermsDir(d.config), d.permsStore)
	if err != nil {
		return nil, nil, err
	}

	if len(components) == 0 {
		return rpc.ChildrenGlobberInvoker(deviceSuffix, appsSuffix), auth, nil
	}
	// The implementation of the device manager is split up into several
	// invokers, which are instantiated depending on the receiver name
	// prefix.
	switch components[0] {
	case deviceSuffix:
		receiver := device.DeviceServer(&deviceService{
			callback:       d.internal.callback,
			updating:       d.internal.updating,
			restartHandler: d.internal.restartHandler,
			config:         d.config,
			disp:           d,
			uat:            d.uat,
			securityAgent:  d.internal.securityAgent,
		})
		return receiver, auth, nil
	case appsSuffix:
		// Requests to apps/*/*/*/logs are handled locally by LogFileService.
		// Requests to apps/*/*/*/pprof are proxied to the apps' __debug/pprof object.
		// Requests to apps/*/*/*/stats are proxied to the apps' __debug/stats object.
		// Everything else is handled by the Application server.
		if len(components) >= 5 {
			appInstanceDir, err := instanceDir(d.config.Root, components[1:4])
			if err != nil {
				return nil, nil, err
			}
			switch kind := components[4]; kind {
			case "logs":
				logsDir := filepath.Join(appInstanceDir, "logs")
				suffix := naming.Join(components[5:]...)
				appSpecificAuthorizer, err := newAppSpecificAuthorizer(auth, d.config, components[1:], d.permsStore)
				if err != nil {
					return nil, nil, err
				}
				return logreaderlib.NewLogFileService(logsDir, suffix), appSpecificAuthorizer, nil
			case "pprof", "stats":
				info, err := loadInstanceInfo(nil, appInstanceDir)
				if err != nil {
					return nil, nil, err
				}
				if !instanceStateIs(appInstanceDir, device.InstanceStateRunning) {
					return nil, nil, verror.New(ErrInvalidSuffix, nil)
				}
				var desc []rpc.InterfaceDesc
				switch kind {
				case "pprof":
					desc = pprof.PProfServer(nil).Describe__()
				case "stats":
					desc = stats.StatsServer(nil).Describe__()
				}
				suffix := naming.Join("__debug", naming.Join(components[4:]...))
				remote := naming.JoinAddressName(info.AppCycleMgrName, suffix)

				// Use hierarchical auth with debugacls under debug access.
				appSpecificAuthorizer, err := newAppSpecificAuthorizer(auth, d.config, components[1:], d.permsStore)
				if err != nil {
					return nil, nil, err
				}
				return newProxyInvoker(remote, access.Debug, desc), appSpecificAuthorizer, nil
			}
		}
		receiver := device.ApplicationServer(&appService{
			config:     d.config,
			suffix:     components[1:],
			uat:        d.uat,
			permsStore: d.permsStore,
			runner: &appRunner{
				reap:          d.internal.reap,
				callback:      d.internal.callback,
				securityAgent: d.internal.securityAgent,
				mtAddress:     d.mtAddress,
			},
		})
		appSpecificAuthorizer, err := newAppSpecificAuthorizer(auth, d.config, components[1:], d.permsStore)
		if err != nil {
			return nil, nil, err
		}
		return receiver, appSpecificAuthorizer, nil
	case configSuffix:
		if len(components) != 2 {
			return nil, nil, verror.New(ErrInvalidSuffix, nil)
		}
		receiver := s_device.ConfigServer(&configService{
			callback: d.internal.callback,
			suffix:   components[1],
		})
		// The nil authorizer ensures that only principals blessed by
		// the device manager can talk back to it.  All apps started by
		// the device manager should fall in that category.
		//
		// TODO(caprita,rjkroege): We should further refine this, by
		// only allowing the app to update state referring to itself
		// (and not other apps).
		return receiver, nil, nil
	default:
		return nil, nil, verror.New(ErrInvalidSuffix, nil)
	}
}

// testModeDispatcher is a wrapper around the real dispatcher. It returns the
// exact same object as the real dispatcher, but the authorizer only allows
// calls to "device".Delete().
type testModeDispatcher struct {
	realDispatcher rpc.Dispatcher
}

func (d *testModeDispatcher) Lookup(suffix string) (interface{}, security.Authorizer, error) {
	obj, _, err := d.realDispatcher.Lookup(suffix)
	return obj, d, err
}

func (testModeDispatcher) Authorize(ctx *context.T, call security.Call) error {
	if call.Suffix() == deviceSuffix && call.Method() == "Delete" {
		vlog.Infof("testModeDispatcher.Authorize: Allow %q.%s()", call.Suffix(), call.Method())
		return nil
	}
	vlog.Infof("testModeDispatcher.Authorize: Reject %q.%s()", call.Suffix(), call.Method())
	return verror.New(ErrInvalidSuffix, nil)
}

func newAppSpecificAuthorizer(sec security.Authorizer, config *config.State, suffix []string, getter pathperms.PermsGetter) (security.Authorizer, error) {
	// TODO(rjkroege): This does not support <appname>.Start() to start all
	// instances. Correct this.

	// If we are attempting a method invocation against "apps/", we use the root
	// Permissions.
	if len(suffix) == 0 || len(suffix) == 1 {
		return sec, nil
	}
	// Otherwise, we require a per-installation and per-instance Permissions file.
	if len(suffix) == 2 {
		p, err := installationDirCore(suffix, config.Root)
		if err != nil {
			return nil, verror.New(ErrOperationFailed, nil, fmt.Sprintf("newAppSpecificAuthorizer failed: %v", err))
		}
		return pathperms.NewHierarchicalAuthorizer(PermsDir(config), path.Join(p, "acls"), getter)
	}
	// Use the special debugacls for instance/logs, instance/pprof, instance/stats.
	if len(suffix) > 3 && (suffix[3] == "logs" || suffix[3] == "pprof" || suffix[3] == "stats") {
		p, err := instanceDir(config.Root, suffix[0:3])
		if err != nil {
			return nil, verror.New(ErrOperationFailed, nil, fmt.Sprintf("newAppSpecificAuthorizer failed: %v", err))
		}
		return pathperms.NewHierarchicalAuthorizer(PermsDir(config), path.Join(p, "debugacls"), getter)
	}

	p, err := instanceDir(config.Root, suffix[0:3])
	if err != nil {
		return nil, verror.New(ErrOperationFailed, nil, fmt.Sprintf("newAppSpecificAuthorizer failed: %v", err))
	}
	return pathperms.NewHierarchicalAuthorizer(PermsDir(config), path.Join(p, "acls"), getter)
}
