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

package artifacts

import (
	"context"
	"fmt"
	"io"
	"path"
	"strings"

	"cloud.google.com/go/storage"
	"go.fuchsia.dev/fuchsia/tools/lib/osmisc"
	"google.golang.org/api/iterator"
)

// The default name of a test's output file. We only store a single file containing a
// test's combined stdout and stderr streams today.  This will change in the future.
const DefaultTestOutputName = "stdout-stderr.txt"

// Directory is an interface for interacting with a Cloud Storage "directory".
type Directory interface {
	Object(string) *storage.ObjectHandle
	CopyFile(ctx context.Context, src, dest string) error
	List(context.Context, string) ([]string, error)
}

// BuildDirectory represents a Fuchsia CI build's artifact directory. Refer to the
// layout in doc.go for the layout of this directory. When amending the layout, prefer
// adding convenience methods on this type to encourages all clients to create objects
// within this BuildDirectory using the same layout.
type BuildDirectory struct {
	*directory
}

// NewTestOutputObject creates a new ObjectHandle to hold the output of the given test
// execution in this BuildDirectory. testName is the name of the test, envName is the
// canonical name of the test environment. Both are normalized according to
// normalizePathSegment.
func (d BuildDirectory) NewTestOutputObject(ctx context.Context, testName, envName string) *storage.ObjectHandle {
	return d.cd("tests").cd(testName).cd(envName).Object(DefaultTestOutputName)
}

// directory is a handle to a Cloud Storage "directory". It provides a minimal
// filesystem-like interface for a Cloud Storage object hierarchy where "/" is used as the
// path separator. Any methods added to this struct are forward to other directory types.
type directory struct {
	bucket *storage.BucketHandle
	root   string
}

// Object returns a handle to the given object within this directory. objPath is the path to
// the object relative to this directory.
func (d *directory) Object(objPath string) *storage.ObjectHandle {
	objPath = path.Join(d.root, objPath)
	return d.bucket.Object(objPath)
}

// CopyFile copies the object from src to dst, creating all the parent directories
// of dest if they don't exist.
func (d *directory) CopyFile(ctx context.Context, src, dest string) error {
	obj := d.Object(src)
	input, err := obj.NewReader(ctx)
	if err != nil {
		return err
	}

	output, err := osmisc.CreateFile(dest)
	if err != nil {
		return err
	}

	_, err = io.Copy(output, input)
	return err
}

// List lists all of the objects in this directory with the given prefix. If prefix == "",
// it will list everything in this directory.
func (d *directory) List(ctx context.Context, prefix string) ([]string, error) {
	prefix = path.Join(d.root, prefix)
	iter := d.bucket.Objects(ctx, &storage.Query{
		Prefix: prefix,
	})

	var items []string
	for {
		attrs, err := iter.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			return nil, err
		}
		items = append(items, strings.TrimPrefix(attrs.Name, d.root+"/"))
	}

	return items, nil
}

// CD returns a handle to some child directory of this directory. directChild should be a
// direct child of the current directory, not a grandchild or any entry deeper in the
// tree. The child's name is normalized according to normalizePathSegment, so using a
// nested path may result in an unexpected file tree.
func (d *directory) cd(directChild string) *directory {
	return &directory{
		bucket: d.bucket,
		root:   fmt.Sprintf("%s/%s", d.root, normalizePathSegment(directChild)),
	}
}
