// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// +build !build_with_native_toolchain

package pkgfs

import (
	"bytes"
	"encoding/json"
	"log"
	"os"
	"regexp"
	"strings"
	"syscall/zx"
	"time"

	"go.fuchsia.dev/fuchsia/src/lib/thinfs/fs"
	"go.fuchsia.dev/fuchsia/src/sys/pkg/bin/pm/pkg"
	"go.fuchsia.dev/fuchsia/src/sys/pkg/lib/far/go"
)

const (
	identityBlob = "15ec7bf0b50732b49f8228e07d24365338f9e3ab994b00af08e5a3bffe55fd8b"
)

var merklePat = regexp.MustCompile("^[0-9a-f]{64}$")

/*
The following VNodes are defined in this file:

/install           - installDir
/install/pkg       - installPkgDir
/install/pkg/{f}   - installFile{isPkg:true}
/install/blob      - installBlobDir
/install/blob/{f}  - installFile{isPkg:false}
*/

// installDir is located at /install.
type installDir struct {
	unsupportedDirectory

	fs *Filesystem
}

func (d *installDir) Dup() (fs.Directory, error) {
	return d, nil
}

func (d *installDir) Stat() (int64, time.Time, time.Time, error) {
	return 0, d.fs.mountTime, d.fs.mountTime, nil
}

func (d *installDir) Open(name string, flags fs.OpenFlags) (fs.File, fs.Directory, *fs.Remote, error) {
	name = clean(name)
	if name == "" {
		return nil, d, nil, nil
	}

	parts := strings.SplitN(name, "/", 2)

	var nd fs.Directory
	switch parts[0] {
	case "pkg":
		nd = &installPkgDir{fs: d.fs}
	case "blob":
		nd = &installBlobDir{fs: d.fs}
	default:
		return nil, nil, nil, fs.ErrNotFound
	}

	if len(parts) == 1 {
		if flags.Directory() {
			return nil, nd, nil, nil
		}
		return nil, nd, nil, fs.ErrNotSupported
	}

	return nd.Open(parts[1], flags)
}

func (d *installDir) Read() ([]fs.Dirent, error) {
	return []fs.Dirent{dirDirEnt("pkg"), dirDirEnt("blob")}, nil
}

func (d *installDir) Close() error {
	return nil
}

// installPkgDir is located at /install/pkg
type installPkgDir struct {
	unsupportedDirectory

	fs *Filesystem
}

func (d *installPkgDir) Dup() (fs.Directory, error) {
	return d, nil
}

func (d *installPkgDir) Stat() (int64, time.Time, time.Time, error) {
	return 0, d.fs.mountTime, d.fs.mountTime, nil
}

func (d *installPkgDir) Open(name string, flags fs.OpenFlags) (fs.File, fs.Directory, *fs.Remote, error) {
	name = clean(name)
	if name == "" {
		return nil, d, nil, nil
	}

	if !flags.Create() {
		return nil, nil, nil, fs.ErrNotSupported
	}

	f := &installFile{fs: d.fs, name: name, isPkg: true}
	err := f.open()
	return f, nil, nil, err
}

func (d *installPkgDir) Read() ([]fs.Dirent, error) {
	return []fs.Dirent{}, nil
}

func (d *installPkgDir) Close() error {
	return nil
}

// installBlobDir is located at /install/blob
type installBlobDir struct {
	unsupportedDirectory

	fs *Filesystem
}

func (d *installBlobDir) Dup() (fs.Directory, error) {
	return d, nil
}

func (d *installBlobDir) Stat() (int64, time.Time, time.Time, error) {
	return 0, d.fs.mountTime, d.fs.mountTime, nil
}

func (d *installBlobDir) Open(name string, flags fs.OpenFlags) (fs.File, fs.Directory, *fs.Remote, error) {
	name = clean(name)
	if name == "" {
		return nil, d, nil, nil
	}

	// TODO(raggi): support write resumption..

	if !flags.Create() {
		return nil, nil, nil, fs.ErrNotSupported
	}

	f := &installFile{fs: d.fs, name: name, isPkg: false}
	var err error
	if !flags.Path() {
		err = f.open()
	}
	return f, nil, nil, err
}

func (d *installBlobDir) Read() ([]fs.Dirent, error) {
	return []fs.Dirent{}, nil
}

func (d *installBlobDir) Close() error {
	return nil
}

type installFile struct {
	unsupportedFile
	fs *Filesystem

	isPkg bool

	size    uint64
	written uint64
	name    string

	blob *os.File
}

func (f *installFile) open() error {
	if !merklePat.Match([]byte(f.name)) {
		return fs.ErrInvalidArgs
	}

	var err error

	// TODO(raggi): propagate flags instead to allow for resumption and so on
	f.blob, err = f.fs.blobfs.OpenFile(f.name, os.O_WRONLY|os.O_CREATE, 0777)

	// When opening a blob for write, blobfs returns a permission error if
	// the blob is in the process of being written or already exists. If we
	// can confirm the blob is readable, report to the caller that it
	// already exists. Otherwise, bubble the error to the caller without
	// fulfilling the need.
	if os.IsPermission(err) {
		if !f.fs.blobfs.HasBlob(f.name) {
			return goErrToFSErr(err)
		}

		// "Fulfill" any needs against the blob that was attempted to be written.
		f.fs.index.Fulfill(f.name)

		if f.isPkg {
			// Importing a package file that is already present in blobfs could fail for
			// a number of reasons, such as the package being invalid, and so on. We need
			// to report such cases back to the caller. In the case where we import fine,
			// we must fall through to passing ErrAlreadyExists back to the caller, so
			// that they know that the package file itself is already complete. Getting
			// `fs.ErrAlreadyExists` on a package meta.far write does not in and of
			// itself indicate that the whole package is present, only that the package
			// metadata blob is present.
			if err := f.importPackage(); err != nil {
				return err
			}
		}
		return fs.ErrAlreadyExists
	}

	if err != nil {
		return goErrToFSErr(err)
	}

	if f.isPkg {
		f.fs.index.Installing(f.name)
	}
	return nil
}

func (f *installFile) Write(p []byte, off int64, whence int) (int, error) {
	var err error
	n := 0

	if whence != fs.WhenceFromCurrent || off != 0 {
		err = &zx.Error{Status: zx.ErrNotSupported}
		return n, goErrToFSErr(err)
	}

	// It is illegal to write past the truncated size of a blob.
	if f.written > f.size {
		err = &zx.Error{Status: zx.ErrInvalidArgs}
		return n, goErrToFSErr(err)
	}

	n, err = f.blob.Write(p)
	f.written += uint64(n)

	if f.written >= f.size && err == nil {
		// "Fulfill" any needs against the blob that was attempted to be written.
		f.fs.index.Fulfill(f.name)

		if f.isPkg {
			// If a package installation fails, the error is returned here.
			return n, goErrToFSErr(f.importPackage())
		}
	}

	return n, goErrToFSErr(err)
}

func (f *installFile) Close() error {
	if f.blob == nil {
		return nil
	}

	if err := f.blob.Close(); err != nil {
		log.Printf("error closing file: %s\n", err)
		return goErrToFSErr(err)
	}

	return nil
}

func (f *installFile) Stat() (int64, time.Time, time.Time, error) {
	return int64(f.written), time.Time{}, time.Time{}, nil
}

func (f *installFile) Truncate(sz uint64) error {
	var err error

	f.size = sz
	err = f.blob.Truncate(int64(f.size))

	if f.size == 0 && f.name == identityBlob && err == nil {
		// Fulfill any needs against the identity blob
		f.fs.index.Fulfill(f.name)
	}

	return goErrToFSErr(err)
}

// importPackage uses f.name to import the package that was just written. It
// returns an fs.Error to report back to the user at write time.
func (f *installFile) importPackage() error {
	return importPackage(f.fs, f.name)
}

// importPackage uses name to import the package that was just written. It
// returns an fs.Error to report back to the user at write time.
func importPackage(f *Filesystem, name string) error {
	b, err := f.blobfs.Open(name)
	if err != nil {
		f.index.InstallingFailedForPackage(name)
		log.Printf("error opening package blob after writing: %s: %s", name, err)
		return fs.ErrFailedPrecondition
	}
	defer b.Close()

	r, err := far.NewReader(b)
	if err != nil {
		f.index.InstallingFailedForPackage(name)
		log.Printf("error reading package archive: %s", err)
		// Note: translates to zx.ErrBadState
		return fs.ErrFailedPrecondition
	}

	pf, err := r.ReadFile("meta/package")
	if err != nil {
		f.index.InstallingFailedForPackage(name)
		log.Printf("error reading package metadata: %s", err)
		// Note: translates to zx.ErrBadState
		return fs.ErrFailedPrecondition
	}

	var p pkg.Package
	err = json.Unmarshal(pf, &p)
	if err != nil {
		f.index.InstallingFailedForPackage(name)
		log.Printf("error parsing package metadata: %s", err)
		// Note: translates to zx.ErrBadState
		return fs.ErrFailedPrecondition
	}

	if err := p.Validate(); err != nil {
		f.index.InstallingFailedForPackage(name)
		log.Printf("package is invalid: %s", err)
		// Note: translates to zx.ErrBadState
		return fs.ErrFailedPrecondition
	}

	// Tell the index the identity of this package.
	f.index.UpdateInstalling(name, p)

	contents, err := r.ReadFile("meta/contents")
	if err != nil {
		log.Printf("error parsing package contents file for %s: %s", p, err)
		// Note: translates to zx.ErrBadState
		return fs.ErrFailedPrecondition
	}

	files := bytes.Split(contents, []byte{'\n'})

	// Note: the following heuristic is coarse and not easy to compute. For small
	// packages enumerating all blobs in blobfs will be slow, but for very large
	// packages it's more likely that polling blobfs the expensive way for missing
	// blobs is going to be expensive. This can be improved by blobfs providing an
	// API to handle this case of "which of the following blobs are already
	// readable"
	mayHaveBlob := func(root string) bool { return true }
	if len(files) > 20 {
		dnames, err := f.blobfs.Blobs()
		if err != nil {
			log.Printf("error readdir blobfs: %s", err)
			// Note: translates to zx.ErrBadState
			return fs.ErrFailedPrecondition
		}
		names := map[string]struct{}{}
		for _, name := range dnames {
			names[name] = struct{}{}
		}
		mayHaveBlob = func(root string) bool {
			_, found := names[root]
			return found
		}
	}

	needBlobs := make(map[string]struct{})
	foundBlobs := make(map[string]struct{})
	needsCount := 0
	for i := range files {
		// Silence apparent errors from last line in file/empty lines.
		if len(files[i]) == 0 {
			continue
		}
		parts := bytes.SplitN(files[i], []byte{'='}, 2)
		if len(parts) != 2 {
			log.Printf("skipping bad package entry: %q", files[i])
			continue
		}
		root := string(parts[1])

		if mayHaveBlob(root) && f.blobfs.HasBlob(root) {
			foundBlobs[root] = struct{}{}
			continue
		}

		needsCount++
		needBlobs[root] = struct{}{}
	}

	// NOTE: the EEXIST returned here is sometimes not strictly "this package was
	// already activated", as the package may have just been activated during the
	// above loop that calls fulfill with each blob that is found that already
	// exists. Doing otherwise would significantly harm performance, as it would
	// require a strong consistency rather than an eventual consistency model, that
	// requires global locking of the filesystem. What this means in the not
	// entirely correct case is either:
	// a) we raced another process that was fulfilling the same needs as this
	//    package.
	// b) all of the content was already on the system, but the package was missing
	//    from the index.
	// This state could be improved if there was an in-memory precomputed index of
	// all active meta.far blobs on the system.
	if needsCount == 0 {
		// It is possible that we already had all of the content for a package at the
		// time when importPackage starts, for example if a package is updated and
		// then reverted to a prior version wihtout GC. In that case, we should still
		// activate the package, even though there is nothing to fulfill.
		f.index.Add(p, name)
		return fs.ErrAlreadyExists
	}

	// We tell the index about needs that we have which were explicitly not found
	// on the system.
	err = goErrToFSErr(f.index.AddNeeds(name, needBlobs))

	// In order to ensure eventual consistency in the case where multiple processes
	// are racing on these needs, we must re-publish all of those fulfillments
	// after publishing the locally discovered needs.
	for blob := range foundBlobs {
		f.index.Fulfill(blob)
	}

	// AddNeeds may return os.ErrExist if the package activation won the race
	// between our needs check loop above, and the following registration of the
	// packages needs.
	return err
}
