// 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 config handles configuration state passed across instances of the
// device manager.
//
// The State object captures setting that the device manager needs to be aware
// of when it starts.  This is passed to the first invocation of the device
// manager, and then passed down from old device manager to new device manager
// upon update.  The device manager has an implementation-dependent mechanism
// for parsing and passing state, which is encapsulated by the state sub-package
// (currently, the mechanism uses environment variables).  When instantiating a
// new instance of the device manager service, the developer needs to pass in a
// copy of State.  They can obtain this by calling Load, which captures any
// config state passed by a previous version of device manager during update.
// Any new version of the device manager must be able to decode a previous
// version's config state, even if the new version changes the mechanism for
// passing this state (that is, device manager implementations must be
// backward-compatible as far as accepting and passing config state goes).
// TODO(caprita): add config state versioning?
package config

import (
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"
	"strings"

	"v.io/x/ref/envvar"

	"v.io/v23/services/application"
	"v.io/v23/verror"
)

const pkgPath = "v.io/x/ref/services/device/internal/config"

var (
	errNeedName           = verror.Register(pkgPath+".errNeedName", verror.NoRetry, "{1:}{2:} Name cannot be empty{:_}")
	errNeedRoot           = verror.Register(pkgPath+".errNeedRoot", verror.NoRetry, "{1:}{2:} Root cannot be empty{:_}")
	errNeedCurrentLink    = verror.Register(pkgPath+".errNeedCurrentLink", verror.NoRetry, "{1:}{2:} CurrentLink cannot be empty{:_}")
	errNeedHelper         = verror.Register(pkgPath+".errNeedHelper", verror.NoRetry, "{1:}{2:} Helper must be specified{:_}")
	errCantDecodeEnvelope = verror.Register(pkgPath+".errCantDecodeEnvelope", verror.NoRetry, "{1:}{2:} failed to decode envelope from {3}{:_}")
	errCantEncodeEnvelope = verror.Register(pkgPath+".errCantEncodeEnvelope", verror.NoRetry, "{1:}{2:} failed to encode envelope {3}{:_}")
	errEvalSymlinksFailed = verror.Register(pkgPath+".errEvalSymlinksFailed", verror.NoRetry, "{1:}{2:} EvalSymlinks failed{:_}")
)

// State specifies how the device manager is configured.  This should
// encapsulate what the device manager needs to know and/or be able to mutate
// about its environment.
type State struct {
	// Name is the device manager's object name.  Must be non-empty.
	Name string
	// Envelope is the device manager's application envelope.  If nil, any
	// envelope fetched from the application repository will trigger an
	// update.
	Envelope *application.Envelope
	// Previous holds the local path to the previous version of the device
	// manager.  If empty, revert is disabled.
	Previous string
	// Root is the directory on the local filesystem that contains
	// the applications' workspaces.  Must be non-empty.
	Root string
	// Origin is the application repository object name for the device
	// manager application.  If empty, update is disabled.
	Origin string
	// CurrentLink is the local filesystem soft link that should point to
	// the version of the device manager binary/script through which device
	// manager is started.  Device manager is expected to mutate this during
	// a self-update.  Must be non-empty.
	CurrentLink string
	// Helper is the path to the setuid helper for running applications as
	// specific users.
	Helper string
}

// Validate checks the config state.
func (c *State) Validate() error {
	if c.Name == "" {
		return verror.New(errNeedName, nil)
	}
	if c.Root == "" {
		return verror.New(errNeedRoot, nil)
	}
	if c.CurrentLink == "" {
		return verror.New(errNeedCurrentLink, nil)
	}
	if c.Helper == "" {
		return verror.New(errNeedHelper, nil)
	}
	return nil
}

// Load reconstructs the config state passed to the device manager (presumably
// by the parent device manager during an update).  Currently, this is done via
// environment variables.
func Load() (*State, error) {
	var env *application.Envelope
	if jsonEnvelope := os.Getenv(EnvelopeEnv); jsonEnvelope != "" {
		env = new(application.Envelope)
		if err := json.Unmarshal([]byte(jsonEnvelope), env); err != nil {
			return nil, verror.New(errCantDecodeEnvelope, nil, jsonEnvelope, err)
		}
	}
	return &State{
		Envelope:    env,
		Previous:    os.Getenv(PreviousEnv),
		Root:        os.Getenv(RootEnv),
		Origin:      os.Getenv(OriginEnv),
		CurrentLink: os.Getenv(CurrentLinkEnv),
		Helper:      os.Getenv(HelperEnv),
	}, nil
}

// Save serializes the config state meant to be passed to a child device manager
// during an update, returning a slice of "key=value" strings, which are
// expected to be stuffed into environment variable settings by the caller.
func (c *State) Save(envelope *application.Envelope) ([]string, error) {
	var jsonEnvelope []byte
	if envelope != nil {
		var err error
		if jsonEnvelope, err = json.Marshal(envelope); err != nil {
			return nil, verror.New(errCantEncodeEnvelope, nil, envelope, err)
		}
	}
	var currScript string
	if _, err := os.Lstat(c.CurrentLink); !os.IsNotExist(err) {
		if currScript, err = filepath.EvalSymlinks(c.CurrentLink); err != nil {
			return nil, verror.New(errEvalSymlinksFailed, nil, err)
		}
	}
	settings := map[string]string{
		EnvelopeEnv:    string(jsonEnvelope),
		PreviousEnv:    currScript,
		RootEnv:        c.Root,
		OriginEnv:      c.Origin,
		CurrentLinkEnv: c.CurrentLink,
		HelperEnv:      c.Helper,
	}
	// We need to manually pass the namespace roots to the child, since we
	// currently don't have a way for the child to obtain this information
	// from a config service at start-up.
	roots, _ := envvar.NamespaceRoots()
	var ret []string
	for k, v := range roots {
		ret = append(ret, k+"="+v)
	}
	for k, v := range settings {
		ret = append(ret, k+"="+v)
	}
	return ret, nil
}

// QuoteEnv wraps environment variable values in double quotes, making them
// suitable for inclusion in a bash script.
func QuoteEnv(env []string) (ret []string) {
	for _, e := range env {
		if eqIdx := strings.Index(e, "="); eqIdx > 0 {
			ret = append(ret, fmt.Sprintf("%s=%q", e[:eqIdx], e[eqIdx+1:]))
		} else {
			ret = append(ret, e)
		}
	}
	return
}
