package fat32

import (
	"errors"
	"fmt"
	"math"
	"regexp"
	"strings"
)

// By default, DOS names would be encoded as what Microsoft calls the OEM
// code page. This is however dependant on the code page settings of the
// OS reading the file name as it's not mentioned in FAT32 metadata.
// To get maximum compatibility and make it easy to read in hex editors
// this only encodes ASCII characters and not any specific code page.
// This can still result in garbled data when using a non-latin code page,
// but this is unavoidable.
// This is legal as there is no specific requirements for generating these
// DOS names and any semi-modern system should use the unicode filenames
// anyways.

var invalidDOSNameChar = regexp.MustCompile("^[^A-Z0-9!#$%&'()@^_\x60{}~-]$")

// validDOSName matches names which are valid and unique DOS 8.3 file names as
// well as valid ASCII
var validDOSName = regexp.MustCompile(`^^([A-Z0-9!#$%&'()@^_\x60{}~-]{0,8})(\.[A-Z0-9!#$%&'()-@^_\x60{}~-]{1,3})?$`)

func makeUniqueDOSNames(inodes []*Inode) error {
	taken := make(map[[11]byte]bool)
	var lossyNameInodes []*Inode
	// Make two passes to ensure that names can always be passed through even
	// if they would conflict with a generated name.
	for _, i := range inodes {
		for j := range i.dosName {
			i.dosName[j] = ' '
		}
		nameUpper := strings.ToUpper(i.Name)
		dosParts := validDOSName.FindStringSubmatch(nameUpper)
		if dosParts != nil {
			// Name is pass-through
			copy(i.dosName[:8], []byte(dosParts[1]))
			if len(dosParts[2]) > 0 {
				// Skip the dot, it is implicit
				copy(i.dosName[8:], []byte(dosParts[2][1:]))
			}
			if taken[i.dosName] {
				// Mapping is unique, complain about the actual file name, not
				// the 8.3 one
				return fmt.Errorf("name %q occurs more than once in the same directory", i.Name)
			}
			taken[i.dosName] = true
			continue
		}
		lossyNameInodes = append(lossyNameInodes, i)
	}
	// Willfully ignore the recommended short name generation algorithm as it
	// requires tons of bookkeeping and doesn't result in stable names so
	// cannot be relied on anyway.
	// A FAT32 directory is limited to 2^16 entries (in practice less than half
	// of that because of long file name entries), so 4 hex characters
	// guarantee uniqueness, regardless of the rest of name.
	var nameIdx int
	for _, i := range lossyNameInodes {
		nameUpper := strings.ToUpper(i.Name)
		dotParts := strings.Split(nameUpper, ".")
		for j := range dotParts {
			// Remove all invalid chars
			dotParts[j] = invalidDOSNameChar.ReplaceAllString(dotParts[j], "")
		}
		var fileName string
		lastDotPart := dotParts[len(dotParts)-1]
		if len(dotParts) > 1 && len(dotParts[0]) > 0 && len(lastDotPart) > 0 {
			// We have a valid 8.3 extension
			copy(i.dosName[8:], lastDotPart)
			fileName = strings.Join(dotParts[:len(dotParts)-1], "")
		} else {
			fileName = strings.Join(dotParts[:], "")
		}
		copy(i.dosName[:4], fileName)

		for {
			copy(i.dosName[4:], fmt.Sprintf("%04X", nameIdx))
			nameIdx++
			if nameIdx >= math.MaxUint16 {
				return errors.New("invariant violated: unable to find unique name with 16 bit counter in 16 bit space")
			}
			if !taken[i.dosName] {
				break
			}
		}
	}
	return nil
}
