// Copyright 2015 The Vanadium 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 binarylib

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strconv"
	"strings"

	"v.io/v23/verror"
	"v.io/x/lib/vlog"
)

const (
	checksumFileName  = "checksum"
	dataFileName      = "data"
	lockFileName      = "lock"
	nameFileName      = "name"
	mediaInfoFileName = "mediainfo"
)

// checksumExists checks whether the given part path is valid and
// contains a checksum. The implementation uses the existence of
// the path dir to determine whether the part is valid, and the
// existence of checksum to determine whether the binary part
// exists.
func checksumExists(path string) error {
	switch _, err := os.Stat(path); {
	case os.IsNotExist(err):
		return verror.New(ErrInvalidPart, nil, path)
	case err != nil:
		vlog.Errorf("Stat(%v) failed: %v", path, err)
		return verror.New(ErrOperationFailed, nil, path)
	}
	checksumFile := filepath.Join(path, checksumFileName)
	_, err := os.Stat(checksumFile)
	switch {
	case os.IsNotExist(err):
		return verror.New(verror.ErrNoExist, nil, path)
	case err != nil:
		vlog.Errorf("Stat(%v) failed: %v", checksumFile, err)
		return verror.New(ErrOperationFailed, nil, path)
	default:
		return nil
	}
}

// generatePartPath generates a path for the given binary part.
func (i *binaryService) generatePartPath(part int) string {
	return generatePartPath(i.path, part)
}

func generatePartPath(dir string, part int) string {
	return filepath.Join(dir, fmt.Sprintf("%d", part))
}

// getParts returns a collection of paths to the parts of the binary.
func getParts(path string) ([]string, error) {
	infos, err := ioutil.ReadDir(path)
	if err != nil {
		vlog.Errorf("ReadDir(%v) failed: %v", path, err)
		return []string{}, verror.New(ErrOperationFailed, nil, path)
	}
	nDirs := 0
	for _, info := range infos {
		if info.IsDir() {
			nDirs++
		}
	}
	result := make([]string, nDirs)
	for _, info := range infos {
		if info.IsDir() {
			partName := info.Name()
			idx, err := strconv.Atoi(partName)
			if err != nil {
				vlog.Errorf("Atoi(%v) failed: %v", partName, err)
				return []string{}, verror.New(ErrOperationFailed, nil, path)
			}
			if idx < 0 || idx >= len(infos) || result[idx] != "" {
				return []string{}, verror.New(ErrOperationFailed, nil, path)
			}
			result[idx] = filepath.Join(path, partName)
		} else {
			if info.Name() == nameFileName || info.Name() == mediaInfoFileName {
				continue
			}
			// The only entries should correspond to the part dirs.
			return []string{}, verror.New(ErrOperationFailed, nil, path)
		}
	}
	return result, nil
}

// createObjectNameTree returns a tree of all the valid object names in the
// repository.
func (i *binaryService) createObjectNameTree() *treeNode {
	pattern := i.state.rootDir
	for d := 0; d < i.state.depth; d++ {
		pattern = filepath.Join(pattern, "*")
	}
	pattern = filepath.Join(pattern, "*", nameFileName)
	matches, err := filepath.Glob(pattern)
	if err != nil {
		return nil
	}
	tree := newTreeNode()
	for _, m := range matches {
		name, err := ioutil.ReadFile(m)
		if err != nil {
			continue
		}
		elems := strings.Split(string(name), string(filepath.Separator))
		tree.find(elems, true)
	}
	return tree
}

type treeNode struct {
	children map[string]*treeNode
}

func newTreeNode() *treeNode {
	return &treeNode{children: make(map[string]*treeNode)}
}

func (n *treeNode) find(names []string, create bool) *treeNode {
	for {
		if len(names) == 0 {
			return n
		}
		if next, ok := n.children[names[0]]; ok {
			n = next
			names = names[1:]
			continue
		}
		if create {
			nn := newTreeNode()
			n.children[names[0]] = nn
			n = nn
			names = names[1:]
			continue
		}
		return nil
	}
}
