// Copyright 2019 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 (
	"sort"
	"time"

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

// validationDir has two entries, present and missing which represent the blobs
// from the static index which are in and not in (respectively) blobfs. This
// uses Filesystem.ValidateStaticIndex() to determine what is or is not there.
type validationDir struct {
	unsupportedDirectory
	fs *Filesystem
}

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

	// we only serve two files
	if name != "present" && name != "missing" {
		return nil, nil, nil, fs.ErrNotFound
	}

	// we're read only
	if flags.Write() || flags.Truncate() || flags.Directory() || flags.Append() {
		return nil, nil, nil, fs.ErrNotSupported
	}

	present, missing, err := valDir.fs.ValidateStaticIndex()
	if err != nil {
		return nil, nil, nil, fs.ErrFailedPrecondition
	}

	pEnts := make([]string, 0, len(present))
	for entry := range present {
		pEnts = append(pEnts, entry)
	}

	mEnts := make([]string, 0, len(missing))
	for entry := range missing {
		mEnts = append(mEnts, entry)
	}

	sort.Strings(pEnts)
	sort.Strings(mEnts)

	t := time.Now()
	switch name {
	case "present":
		return &validationFile{unsupportedFile: unsupportedFile("present"), entries: pEnts, statTime: t}, nil, nil, nil
	case "missing":
		return &validationFile{unsupportedFile: unsupportedFile("missing"), entries: mEnts, statTime: t}, nil, nil, nil
	default:
		// should actually be impossible to get here given the check above
		return nil, nil, nil, fs.ErrNotFound
	}
}

func (valDir *validationDir) Read() ([]fs.Dirent, error) {
	return []fs.Dirent{
		fileDirEnt("missing"),
		fileDirEnt("present"),
	}, nil
}

func (valDir *validationDir) Stat() (int64, time.Time, time.Time, error) {
	t := time.Now()
	return 2, t, t, nil
}

const lineSize = int64(64 + 1)

// validationFile represents the present or missing blobs in the static index.
// The size of the file as reported by Stat() indicates the number of present
// or missing blobs
type validationFile struct {
	unsupportedFile
	entries  []string
	statTime time.Time
	seek     int64
}

func (valFile *validationFile) Stat() (int64, time.Time, time.Time, error) {
	return int64(len(valFile.entries)) * lineSize, valFile.statTime, valFile.statTime, nil
}

// Read reads a maximum of len(p) bytes into "p" from the file at a location decided by "off"
// and "whence".
// The seek position is only updated if fs.WhenceFromCurrent is passed as whence.
func (valFile *validationFile) Read(p []byte, off int64, whence int) (int, error) {
	if whence == fs.WhenceFromCurrent {
		valFile.seek += off
	} else {
		return 0, fs.ErrInvalidArgs
	}

	if valFile.seek < 0 {
		valFile.seek = 0
	}

	listOffset := valFile.seek / lineSize
	entPos := valFile.seek % lineSize

	copied := 0
	for ; copied < len(p); listOffset++ {
		if listOffset >= int64(len(valFile.entries)) {
			if copied < len(p) {
				return copied, fs.ErrEOF
			}
			break
		}

		src := []byte(valFile.entries[listOffset][entPos:])
		entPos = 0
		moved := copy(p[copied:], src)
		copied += moved
		valFile.seek += int64(moved)

		if len(p) > copied {
			p[copied] = '\n'
			copied++
			valFile.seek++
		}

		if copied == len(p) {
			return len(p), nil
		}
	}

	return copied, nil
}

func (valFile *validationFile) Close() error {
	valFile.seek = 0
	return nil
}
