package asset

import (
	"context"
	"fmt"
	"path/filepath"

	"gocloud.dev/blob"
)

type Asset interface {
	// Sub returns a new Asset with the given paths as a subdirectory of the current asset.
	Sub(paths ...string) Asset
	// Bucket returns a blob.Bucket that represents the asset's storage location.
	// Call blob.Bucket.Close when done to release resources.
	//
	// A new bucket is opened for every call because closing a bucket returned by
	// blob.PrefixedBucket also closes its underlying bucket.
	Bucket(ctx context.Context) (*blob.Bucket, error)
}

type core interface {
	OpenBucket(ctx context.Context) (*blob.Bucket, error)
}

type asset struct {
	prefix string
	core   core
}

func (a *asset) Sub(paths ...string) Asset {
	return &asset{
		prefix: filepath.Join(a.prefix, filepath.Join(paths...)),
		core:   a.core,
	}
}

func (a *asset) Bucket(ctx context.Context) (*blob.Bucket, error) {
	root, err := a.core.OpenBucket(ctx)
	if err != nil {
		return nil, fmt.Errorf("open root bucket failed: %w", err)
	}

	if a.prefix == "" {
		return root, nil
	}

	return blob.PrefixedBucket(root, a.prefix+"/"), nil
}
