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

import (
	"encoding/json"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

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

	"v.io/x/ref/services/discharger"
	"v.io/x/ref/services/role"

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

const requiredSuffix = security.ChainSeparator + role.RoleSuffix

// NewDispatcher returns a dispatcher object for a role service and its
// associated discharger service.
// The configRoot is the top level directory where the role configuration files
// are stored.
// The dischargerLocation is the object name or address of the discharger
// service for the third-party caveats attached to the role blessings returned
// by the role service.
func NewDispatcher(configRoot, dischargerLocation string) rpc.Dispatcher {
	return &dispatcher{&serverConfig{configRoot, dischargerLocation}}
}

type serverConfig struct {
	root               string
	dischargerLocation string
}

type dispatcher struct {
	config *serverConfig
}

func (d *dispatcher) Lookup(suffix string) (interface{}, security.Authorizer, error) {
	if len(suffix) == 0 {
		return discharger.DischargerServer(&dischargerImpl{d.config}), &openAuthorizer{}, nil
	}
	fileName := filepath.Join(d.config.root, filepath.FromSlash(suffix+".conf"))
	if !strings.HasPrefix(fileName, d.config.root) {
		// Guard against ".." in the suffix that could be used to read
		// files outside of the config root.
		return nil, nil, verror.New(verror.ErrNoExistOrNoAccess, nil)
	}
	roleConfig, err := loadExpandedConfig(fileName, nil)
	if err != nil && !os.IsNotExist(err) {
		// The config file exists, but we failed to read it for some
		// reason. This is likely a server configuration error.
		vlog.Errorf("loadConfig(%q, %q): %v", d.config.root, suffix, err)
		return nil, nil, verror.Convert(verror.ErrInternal, nil, err)
	}
	obj := &roleService{serverConfig: d.config, role: suffix, roleConfig: roleConfig}
	return role.RoleServer(obj), &authorizer{roleConfig}, nil
}

type openAuthorizer struct{}

func (openAuthorizer) Authorize(*context.T, security.Call) error {
	return nil
}

type authorizer struct {
	config *Config
}

func (a *authorizer) Authorize(ctx *context.T, call security.Call) error {
	if call.Method() == "__Glob" {
		// The Glob implementation only shows objects that the caller
		// has access to. So this blanket approval is OK.
		return nil
	}
	if a.config == nil {
		return verror.New(verror.ErrNoExistOrNoAccess, ctx)
	}
	remoteBlessingNames, _ := security.RemoteBlessingNames(ctx, call)

	if hasAccess(a.config, remoteBlessingNames) {
		return nil
	}
	return verror.New(verror.ErrNoExistOrNoAccess, ctx)
}

func hasAccess(c *Config, blessingNames []string) bool {
	for _, pattern := range c.Members {
		if pattern.MatchedBy(blessingNames...) {
			return true
		}
	}
	return false
}

func loadExpandedConfig(fileName string, seenFiles map[string]struct{}) (*Config, error) {
	if seenFiles == nil {
		seenFiles = make(map[string]struct{})
	}
	if _, seen := seenFiles[fileName]; seen {
		return nil, nil
	}
	seenFiles[fileName] = struct{}{}
	c, err := loadConfig(fileName)
	if err != nil {
		return nil, err
	}
	parentDir := filepath.Dir(fileName)
	for _, imp := range c.ImportMembers {
		f := filepath.Join(parentDir, filepath.FromSlash(imp+".conf"))
		ic, err := loadExpandedConfig(f, seenFiles)
		if err != nil {
			vlog.Errorf("loadExpandedConfig(%q) failed: %v", f, err)
			continue
		}
		if ic == nil {
			continue
		}
		c.Members = append(c.Members, ic.Members...)
	}
	c.ImportMembers = nil
	dedupMembers(c)
	return c, nil
}

func loadConfig(fileName string) (*Config, error) {
	contents, err := ioutil.ReadFile(fileName)
	if err != nil {
		return nil, err
	}
	var c Config
	if err := json.Unmarshal(contents, &c); err != nil {
		return nil, err
	}
	for i, pattern := range c.Members {
		if p := string(pattern); !strings.HasSuffix(p, requiredSuffix) {
			c.Members[i] = security.BlessingPattern(p + requiredSuffix)
		}
	}
	return &c, nil
}

func dedupMembers(c *Config) {
	members := make(map[security.BlessingPattern]struct{})
	for _, m := range c.Members {
		members[m] = struct{}{}
	}
	c.Members = []security.BlessingPattern{}
	for m := range members {
		c.Members = append(c.Members, m)
	}
}
