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

import (
	"encoding/binary"
	"io"
	"os"
	"strconv"
	"sync"
	"unicode/utf8"

	"v.io/v23/verror"
)

var (
	ErrNoVersion          = verror.Register(pkgPath+".ErrNoVersion", verror.NoRetry, "{1:}{2:} "+ExecVersionVariable+" environment variable missing{:_}")
	ErrUnsupportedVersion = verror.Register(pkgPath+".ErrUnsupportedVersion", verror.NoRetry, "{1:}{2:} Unsupported version of v.io/x/ref/lib/exec request by "+ExecVersionVariable+" environment variable{:_}")

	errDifferentStatusSent = verror.Register(pkgPath+".errDifferentStatusSent", verror.NoRetry, "{1:}{2:} A different status: {3} has already been sent{:_}")
	errPartialRead         = verror.Register(pkgPath+".PartialRead", verror.NoRetry, "{1:}{2:} partial read{:_}")
)

type ChildHandle struct {
	// Config is passed down from the parent.
	Config Config
	// Secret is a secret passed to the child by its parent via a
	// trusted channel.
	Secret string
	// statusPipe is a pipe that is used to notify the parent that the child
	// process has started successfully. It is meant to be invoked by the
	// vanadium framework to notify the parent that the child process has
	// successfully started.
	statusPipe *os.File

	// statusMu protexts sentStatus and statusErr and prevents us from trying to
	// send multiple status updates to the parent.
	statusMu sync.Mutex
	// sentStatus records the status that was already sent to the parent.
	sentStatus string
	// statusErr records the error we received, if any, when sentStatus
	// was sent.
	statusErr error
}

var (
	childHandle    *ChildHandle
	childHandleErr error
	once           sync.Once
)

// FileOffset accounts for the file descriptors that are always passed
// to the child by the parent: stderr, stdin, stdout, data read, and
// status write. Any extra files added by the client will follow
// fileOffset.
const FileOffset = 5

// GetChildHandle returns a ChildHandle that can be used to signal
// that the child is 'ready' (by calling SetReady) to its parent or to
// retrieve data securely passed to this process by its parent. For
// instance, a secret intended to create a secure communication
// channels and or authentication.
//
// If the child is relying on exec.Cmd.ExtraFiles then its first file
// descriptor will not be 3, but will be offset by extra files added
// by the framework. The developer should use the NewExtraFile method
// to robustly get their extra files with the correct offset applied.
func GetChildHandle() (*ChildHandle, error) {
	once.Do(func() {
		childHandle, childHandleErr = createChildHandle()
	})
	return childHandle, childHandleErr
}

func (c *ChildHandle) writeStatus(status, detail string) error {
	c.statusMu.Lock()
	defer c.statusMu.Unlock()

	if c.sentStatus == "" {
		c.sentStatus = status
		status = status + detail
		toWrite := make([]byte, 0, len(status))
		var buf [utf8.UTFMax]byte
		// This replaces any invalid utf-8 bytes in the status string with the
		// Unicode replacement character.  This ensures that we only send valid
		// utf-8 (followed by the eofChar).
		for _, r := range status {
			n := utf8.EncodeRune(buf[:], r)
			toWrite = append(toWrite, buf[:n]...)
		}
		toWrite = append(toWrite, eofChar)
		_, c.statusErr = c.statusPipe.Write(toWrite)
		c.statusPipe.Close()
	} else if c.sentStatus != status {
		return verror.New(errDifferentStatusSent, nil, c.sentStatus)
	}
	return c.statusErr
}

// SetReady writes a 'ready' status to its parent.
// Only one of SetReady or SetFailed can be called, attempting to send
// both will fail.  In addition the status is only sent once to the parent
// subsequent calls will return immediately with the same error that was
// returned on the first call (possibly nil).
func (c *ChildHandle) SetReady() error {
	return c.writeStatus(readyStatus, strconv.Itoa(os.Getpid()))
}

// SetFailed writes a 'failed' status to its parent.
func (c *ChildHandle) SetFailed(oerr error) error {
	return c.writeStatus(failedStatus, oerr.Error())
}

// NewExtraFile creates a new file handle for the i-th file descriptor after
// discounting stdout, stderr, stdin and the files reserved by the framework for
// its own purposes.
func (c *ChildHandle) NewExtraFile(i uintptr, name string) *os.File {
	return os.NewFile(i+FileOffset, name)
}

func createChildHandle() (*ChildHandle, error) {
	// TODO(cnicolaou): need to use major.minor.build format for
	// version #s.
	switch os.Getenv(ExecVersionVariable) {
	case "":
		return nil, verror.New(ErrNoVersion, nil)
	case version1:
		os.Setenv(ExecVersionVariable, "")
	default:
		return nil, verror.New(ErrUnsupportedVersion, nil)
	}
	dataPipe := os.NewFile(3, "data_rd")
	serializedConfig, err := decodeString(dataPipe)
	if err != nil {
		return nil, err
	}
	cfg := NewConfig()
	if err := cfg.MergeFrom(serializedConfig); err != nil {
		return nil, err
	}
	secret, err := decodeString(dataPipe)
	if err != nil {
		return nil, err
	}
	childHandle = &ChildHandle{
		Config:     cfg,
		Secret:     secret,
		statusPipe: os.NewFile(4, "status_wr"),
	}
	return childHandle, nil
}

func decodeString(r io.Reader) (string, error) {
	var l int64 = 0
	if err := binary.Read(r, binary.BigEndian, &l); err != nil {
		return "", err
	}
	var data []byte = make([]byte, l)
	if n, err := r.Read(data); err != nil || int64(n) != l {
		if err != nil {
			return "", err
		} else {
			return "", verror.New(errPartialRead, nil)
		}
	}
	return string(data), nil
}
