// 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 (
	"strings"
	"time"

	"go.fuchsia.dev/fuchsia/src/lib/thinfs/fs"
)

// needsRoot presents the following tree:
//  /pkgfs/needs/packages/$PACKAGE_HASH/$BLOB_HASH
// the files are "needsFile" vnodes, so they're writable to blobfs.
type needsRoot struct {
	unsupportedDirectory

	fs *Filesystem
}

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

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

func (d *needsRoot) 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)

	switch parts[0] {
	case "packages":
		npr := &needsPkgRoot{unsupportedDirectory: unsupportedDirectory("/needs/packages"), fs: d.fs}
		if len(parts) > 1 {
			return npr.Open(parts[1], flags)
		}
		return nil, npr, nil, nil

	default:
		if len(parts) != 1 || flags.Create() {
			return nil, nil, nil, fs.ErrNotSupported
		}

		return nil, nil, nil, fs.ErrNotFound
	}
}

func (d *needsRoot) Read() ([]fs.Dirent, error) {
	return []fs.Dirent{dirDirEnt("packages")}, nil
}

func (d *needsRoot) Stat() (int64, time.Time, time.Time, error) {
	// TODO(raggi): provide more useful values
	return 0, d.fs.mountTime, d.fs.mountTime, nil
}

// needsPkgRoot serves a directory that indexes the blobs needed to fulfill a
// package that is presently part way through caching.
type needsPkgRoot struct {
	unsupportedDirectory

	fs *Filesystem
}

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

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

func (d *needsPkgRoot) 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)

	root := parts[0]

	if !d.fs.index.IsInstalling(root) {
		return nil, nil, nil, fs.ErrNotFound
	}

	pkgDir := &needsPkgDir{fs: d.fs, pkgRoot: root}

	if len(parts) > 1 {
		return pkgDir.Open(parts[1], flags)
	}

	return nil, pkgDir, nil, nil
}

func (d *needsPkgRoot) Read() ([]fs.Dirent, error) {
	blobs := d.fs.index.InstallingList()
	dirents := make([]fs.Dirent, len(blobs))
	for i := range blobs {
		dirents[i] = fileDirEnt(blobs[i])
	}
	return dirents, nil
}

func (d *needsPkgRoot) Stat() (int64, time.Time, time.Time, error) {
	// TODO(raggi): provide more useful values
	return 0, d.fs.mountTime, d.fs.mountTime, nil
}

// needsPkgDir serves a directory that indexes the blobs needed to fulfill a
// package that is presently part way through caching.
type needsPkgDir struct {
	unsupportedDirectory

	fs *Filesystem

	pkgRoot string
}

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

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

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

	if strings.Contains(name, "/") {
		return nil, nil, nil, fs.ErrNotFound
	}

	if !d.fs.index.PkgHasNeed(d.pkgRoot, name) {
		return nil, nil, nil, fs.ErrNotFound
	}

	return &installFile{fs: d.fs, name: name, isPkg: false}, nil, nil, nil
}

func (d *needsPkgDir) Read() ([]fs.Dirent, error) {
	names := d.fs.index.PkgNeedsList(d.pkgRoot)
	dirents := make([]fs.Dirent, len(names))
	for i := range names {
		dirents[i] = fileDirEnt(names[i])
	}
	return dirents, nil
}

func (d *needsPkgDir) Stat() (int64, time.Time, time.Time, error) {
	// TODO(raggi): provide more useful values
	return 0, d.fs.mountTime, d.fs.mountTime, nil
}
