package boxstore

import (
	"fmt"
	"os"
	"path/filepath"

	"warpbox/lib/helpers"
)

const manifestFile = ".warpbox.json"

var uploadRoot = filepath.Join("data", "uploads")

func NewBoxID() (string, error) {
	return helpers.RandomHexID(16)
}

func ValidBoxID(boxID string) bool {
	return helpers.ValidLowerHexID(boxID, 32)
}
func SetUploadRoot(path string) {
	if path == "" {
		return
	}
	uploadRoot = filepath.Clean(path)
}
func UploadRoot() string {
	return uploadRoot
}

func BoxPath(boxID string) string {
	return filepath.Join(uploadRoot, boxID)
}

func safeBoxPath(boxID string) (string, bool) {
	if !ValidBoxID(boxID) {
		return "", false
	}
	return helpers.SafeChildPath(uploadRoot, boxID)
}

func ManifestPath(boxID string) string {
	return filepath.Join(BoxPath(boxID), manifestFile)
}

func SafeBoxFilePath(boxID string, filename string) (string, bool) {
	boxPath, ok := safeBoxPath(boxID)
	if !ok {
		return "", false
	}
	return helpers.SafeChildPath(boxPath, filename)
}

func IsSafeRegularBoxFile(boxID string, filename string) bool {
	path, ok := SafeBoxFilePath(boxID, filename)
	if !ok {
		return false
	}
	return ensureRegularFile(path) == nil
}

func DeleteBox(boxID string) error {
	boxPath, ok := safeBoxPath(boxID)
	if !ok {
		return fmt.Errorf("Invalid box id")
	}
	return os.RemoveAll(boxPath)
}
func ensureRegularFile(path string) error {
	info, err := os.Lstat(path)
	if err != nil {
		return err
	}
	if info.Mode()&os.ModeSymlink != 0 || !info.Mode().IsRegular() {
		return fmt.Errorf("Invalid file")
	}
	return nil
}
