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

import (
	"strings"

	"v.io/v23/context"
	"v.io/v23/rpc"
	"v.io/v23/security"
	wire "v.io/v23/services/syncbase"
	pubutil "v.io/v23/syncbase/util"
	"v.io/v23/verror"
	"v.io/x/ref/services/syncbase/common"
	"v.io/x/ref/services/syncbase/server/interfaces"
)

type dispatcher struct {
	s *service
}

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

func NewDispatcher(s *service) *dispatcher {
	return &dispatcher{s: s}
}

// We always return an AllowEveryone authorizer from Lookup(), and rely on our
// RPC method implementations to perform proper authorization.
var auth security.Authorizer = security.AllowEveryone()

func (disp *dispatcher) Lookup(ctx *context.T, suffix string) (interface{}, security.Authorizer, error) {
	if len(suffix) == 0 {
		return wire.ServiceServer(disp.s), auth, nil
	}
	// Namespace: <serviceName>/<encDbId>/<encCxId>/<encRowKey>
	parts := strings.SplitN(suffix, "/", 3)

	// If the first slash-separated component of suffix is SyncbaseSuffix,
	// dispatch to the sync module.
	if parts[0] == common.SyncbaseSuffix {
		return interfaces.SyncServer(disp.s.sync), auth, nil
	}

	// Validate all name components up front, so that we can avoid doing so in all
	// our method implementations.

	// Note, the slice returned by strings.SplitN is guaranteed to contain at
	// least one element.
	dbId, err := pubutil.DecodeId(parts[0])
	if err == nil {
		err = pubutil.ValidateId(dbId)
	}
	if err != nil {
		return nil, nil, verror.New(wire.ErrInvalidName, ctx, suffix, err)
	}

	var collectionId wire.Id
	if len(parts) > 1 {
		collectionId, err = pubutil.DecodeId(parts[1])
		if err == nil {
			err = pubutil.ValidateId(collectionId)
		}
		if err != nil {
			return nil, nil, verror.New(wire.ErrInvalidName, ctx, suffix, err)
		}
	}

	var rowKey string
	if len(parts) > 2 {
		rowKey, err = pubutil.Decode(parts[2])
		if err == nil {
			err = pubutil.ValidateRowKey(rowKey)
		}
		if err != nil {
			return nil, nil, verror.New(wire.ErrInvalidName, ctx, suffix, err)
		}
	}

	var d *database
	if dInt, err := disp.s.Database(ctx, nil, dbId); err == nil {
		d = dInt.(*database) // panics on failure, as desired
	} else {
		if verror.ErrorID(err) != verror.ErrNoExist.ID {
			// TODO(ivanpi): Panic here? Database() seems to never return other errors.
			return nil, nil, err
		} else {
			// Database does not exist. Create a short-lived database object to
			// service this request.
			d = disp.s.nonexistentDatabaseHandle(dbId)
		}
	}

	// TODO(sadovsky): Is it possible to determine the RPC method from the
	// context? If so, we can check here that the database exists (unless the
	// client is calling Database.Create), and avoid the "d.exists" checks in all
	// the RPC method implementations. Note, this would also require being able
	// to authorize the user to return the appropriate error type (ErrNoExist vs
	// ErrNoExistOrNoAccess), possibly by returning a specialized authorizer.

	if len(parts) == 1 {
		return wire.DatabaseServer(d), auth, nil
	}

	// Note, it's possible for the database to be deleted concurrently with
	// downstream handling of this request. Depending on the order in which things
	// execute, the client may not get an error, but in any case ultimately the
	// store will end up in a consistent state.
	cReq := &collectionReq{
		id: collectionId,
		d:  d,
	}
	if len(parts) == 2 {
		return wire.CollectionServer(cReq), auth, nil
	}

	rReq := &rowReq{
		key: rowKey,
		c:   cReq,
	}
	if len(parts) == 3 {
		return wire.RowServer(rReq), auth, nil
	}

	// TODO(ivanpi): Panic here? This should never happen since we do SplitN.
	return nil, nil, verror.New(wire.ErrInvalidName, ctx, suffix, "too many name components")
}
