// 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 pathperms provides a library to assist servers implementing
// GetPermissions/SetPermissions functions and authorizers where there are
// path-specific Permissions stored individually in files.
// TODO(rjkroege): Add unit tests.
package pathperms

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"sync"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/security"
	"v.io/v23/security/access"
	"v.io/v23/verror"
	"v.io/x/ref/lib/security/serialization"
)

const (
	pkgPath   = "v.io/x/ref/services/internal/pathperms"
	sigName   = "signature"
	permsName = "data"
)

var (
	ErrOperationFailed = verror.Register(pkgPath+".OperationFailed", verror.NoRetry, "{1:}{2:} operation failed{:_}")
)

type pathEntry struct {
	lk sync.Mutex
	c  int
}

// PathStore manages storage of a set of Permissions in the filesystem where each
// path identifies a specific Permissions in the set. PathStore synchronizes
// access to its member Permissions.
type PathStore struct {
	pthlks    map[string]*pathEntry
	lk        sync.Mutex
	ctx       *context.T
	principal security.Principal
}

// NewPathStore creates a new instance of the lock map that uses
// principal to sign stored Permissions files.
func NewPathStore(ctx *context.T) *PathStore {
	return &PathStore{pthlks: make(map[string]*pathEntry), ctx: ctx, principal: v23.GetPrincipal(ctx)}
}

// Get returns the Permissions from the data file in dir.
func (store *PathStore) Get(dir string) (access.Permissions, string, error) {
	permspath := filepath.Join(dir, permsName)
	sigpath := filepath.Join(dir, sigName)
	defer store.lockPath(dir)()
	return getCore(store.ctx, permspath, sigpath)
}

// TODO(rjkroege): Improve lock handling.
func (store *PathStore) lockPath(dir string) func() {
	store.lk.Lock()
	pe, contains := store.pthlks[dir]
	if !contains {
		pe = &pathEntry{}
		store.pthlks[dir] = pe
	}
	pe.c++
	store.lk.Unlock()
	pe.lk.Lock()

	return func() {
		pe.lk.Unlock()
		store.lk.Lock()
		pe.c--
		if pe.c == 0 {
			delete(store.pthlks, dir)
		}
		store.lk.Unlock()
	}
}

func getCore(ctx *context.T, permspath, sigpath string) (access.Permissions, string, error) {
	principal := v23.GetPrincipal(ctx)
	f, err := os.Open(permspath)
	if err != nil {
		// This path is rarely a fatal error so log informationally only.
		ctx.VI(2).Infof("os.Open(%s) failed: %v", permspath, err)
		return nil, "", err
	}
	defer f.Close()

	s, err := os.Open(sigpath)
	if err != nil {
		ctx.Errorf("Signatures for Permissions are required: %s unavailable: %v", permspath, err)
		return nil, "", verror.New(ErrOperationFailed, nil)
	}
	defer s.Close()

	// read and verify the signature of the perms file
	vf, err := serialization.NewVerifyingReader(f, s, principal.PublicKey())
	if err != nil {
		ctx.Errorf("NewVerifyingReader() failed: %v (perms=%s, sig=%s)", err, permspath, sigpath)
		return nil, "", verror.New(ErrOperationFailed, nil)
	}

	perms, err := access.ReadPermissions(vf)
	if err != nil {
		ctx.Errorf("ReadPermissions(%s) failed: %v", permspath, err)
		return nil, "", err
	}
	version, err := ComputeVersion(perms)
	if err != nil {
		ctx.Errorf("pathperms.ComputeVersion failed: %v", err)
		return nil, "", err
	}
	return perms, version, nil
}

// Set writes the specified Permissions to the provided directory with
// enforcement of version synchronization mechanism and locking.
func (store *PathStore) Set(dir string, perms access.Permissions, version string) error {
	_, err := store.SetShareable(dir, perms, version, false, true)
	return err
}

// SetIfAbsent writes the specified Permissions to the provided directory only
// if they don't already exist.  Returns true if the permissions were written,
// and false otherwise (the error is nil if the permissions already exist).
func (store *PathStore) SetIfAbsent(dir string, perms access.Permissions) (bool, error) {
	return store.SetShareable(dir, perms, "", false, false)
}

// SetShareable writes the specified Permissions to the provided
// directory with enforcement of version synchronization mechanism and
// locking with file modes that will give the application read-only
// access to the permissions file.
func (store *PathStore) SetShareable(dir string, perms access.Permissions, version string, shareable, overwrite bool) (bool, error) {
	permspath := filepath.Join(dir, permsName)
	sigpath := filepath.Join(dir, sigName)
	defer store.lockPath(dir)()
	_, oversion, err := getCore(store.ctx, permspath, sigpath)
	if err != nil && !os.IsNotExist(err) {
		return false, verror.New(ErrOperationFailed, nil)
	}
	if !overwrite && err == nil {
		// If overwrite is not set, we need the perms to not already
		// exist; as per previous if test, os.IsNotExist(err) iff err !=
		// nil.
		return false, nil
	}
	if len(version) > 0 && version != oversion {
		return false, verror.NewErrBadVersion(nil)
	}
	if err := write(store.ctx, permspath, sigpath, dir, perms, shareable); err != nil {
		return false, err
	}
	return true, nil
}

// Delete removes the permissions stored in the specified directory.
func (store *PathStore) Delete(dir string) error {
	// NOTE: we're not using RemoveAll(dir) out of an excess of caution (in
	// case a bad dir is passed in).
	permspath := filepath.Join(dir, permsName)
	if err := os.Remove(permspath); err != nil {
		return err
	}
	sigpath := filepath.Join(dir, sigName)
	if err := os.Remove(sigpath); err != nil {
		return err
	}
	if err := os.Remove(dir); err != nil {
		return err
	}
	return nil
}

// write writes the specified Permissions to the permsFile with a
// signature in sigFile.
func write(ctx *context.T, permsFile, sigFile, dir string, perms access.Permissions, shareable bool) error {
	principal := v23.GetPrincipal(ctx)
	filemode := os.FileMode(0600)
	dirmode := os.FileMode(0700)
	if shareable {
		filemode = os.FileMode(0644)
		dirmode = os.FileMode(0711)
	}

	// Create dir directory if it does not exist
	os.MkdirAll(dir, dirmode)
	// Save the object to temporary data and signature files, and then move
	// those files to the actual data and signature file.
	data, err := ioutil.TempFile(dir, permsName)
	if err != nil {
		ctx.Errorf("Failed to open tmpfile data:%v", err)
		return verror.New(ErrOperationFailed, nil)
	}
	defer os.Remove(data.Name())
	sig, err := ioutil.TempFile(dir, sigName)
	if err != nil {
		ctx.Errorf("Failed to open tmpfile sig:%v", err)
		return verror.New(ErrOperationFailed, nil)
	}
	defer os.Remove(sig.Name())
	writer, err := serialization.NewSigningWriteCloser(data, sig, principal, nil)
	if err != nil {
		ctx.Errorf("Failed to create NewSigningWriteCloser:%v", err)
		return verror.New(ErrOperationFailed, nil)
	}
	if err = access.WritePermissions(writer, perms); err != nil {
		ctx.Errorf("Failed to SavePermissions:%v", err)
		return verror.New(ErrOperationFailed, nil)
	}
	if err = writer.Close(); err != nil {
		ctx.Errorf("Failed to Close() SigningWriteCloser:%v", err)
		return verror.New(ErrOperationFailed, nil)
	}
	if err := os.Rename(data.Name(), permsFile); err != nil {
		ctx.Errorf("os.Rename() failed:%v", err)
		return verror.New(ErrOperationFailed, nil)
	}
	if err := os.Chmod(permsFile, filemode); err != nil {
		ctx.Errorf("os.Chmod() failed:%v", err)
		return verror.New(ErrOperationFailed, nil)
	}
	if err := os.Rename(sig.Name(), sigFile); err != nil {
		ctx.Errorf("os.Rename() failed:%v", err)
		return verror.New(ErrOperationFailed, nil)
	}
	if err := os.Chmod(sigFile, filemode); err != nil {
		ctx.Errorf("os.Chmod() failed:%v", err)
		return verror.New(ErrOperationFailed, nil)
	}
	return nil
}

func (store *PathStore) PermsForPath(ctx *context.T, path string) (access.Permissions, bool, error) {
	perms, _, err := store.Get(path)
	if os.IsNotExist(err) {
		return nil, true, nil
	} else if err != nil {
		return nil, false, err
	}
	return perms, false, nil
}

// PrefixPatterns creates a pattern containing all of the prefix patterns of the
// provided blessings.
func PrefixPatterns(blessings []string) []security.BlessingPattern {
	var patterns []security.BlessingPattern
	for _, b := range blessings {
		patterns = append(patterns, security.BlessingPattern(b).PrefixPatterns()...)
	}
	return patterns
}

// PermissionsForBlessings creates the Permissions list that should be used with
// a newly created object.
func PermissionsForBlessings(blessings []string) access.Permissions {
	perms := make(access.Permissions)

	// Add the invoker's blessings and all its prefixes.
	for _, p := range PrefixPatterns(blessings) {
		for _, tag := range access.AllTypicalTags() {
			perms.Add(p, string(tag))
		}
	}
	return perms
}

// NilAuthPermissions creates Permissions that mimics the default authorization
// policy (i.e., Permissions is matched by all blessings that are either
// extensions of one of the local blessings or can be extended to form one of
// the local blessings.)
func NilAuthPermissions(ctx *context.T, call security.Call) access.Permissions {
	perms := make(access.Permissions)
	lb := security.LocalBlessingNames(ctx, call)
	for _, p := range PrefixPatterns(lb) {
		for _, tag := range access.AllTypicalTags() {
			perms.Add(p, string(tag))
		}
	}
	return perms
}
