// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file implements the Mapping data structure.

package main

import (
	"fmt"
	"io"
	"os"
	pathutil "path"
	"strings"
)


// A Mapping object maps relative paths (e.g. from URLs)
// to absolute paths (of the file system) and vice versa.
//
// A Mapping object consists of a list of individual mappings
// of the form: prefix -> path which are interpreted as follows:
// A relative path of the form prefix/tail is to be mapped to
// the absolute path/tail, if that absolute path exists in the file
// system. Given a Mapping object, a relative path is mapped to an
// absolute path by trying each of the individual mappings in order,
// until a valid mapping is found. For instance, for the mapping:
//
//	user   -> /home/user
//	public -> /home/user/public
//	public -> /home/build/public
//
// the relative paths below are mapped to absolute paths as follows:
//
//	user/foo                -> /home/user/foo
//	public/net/rpc/file1.go -> /home/user/public/net/rpc/file1.go
//
// If there is no /home/user/public/net/rpc/file2.go, the next public
// mapping entry is used to map the relative path to:
//
//	public/net/rpc/file2.go -> /home/build/public/net/rpc/file2.go
//
// (assuming that file exists).
//
type Mapping struct {
	list     []mapping
	prefixes []string
}


type mapping struct {
	prefix, path string
}


// Init initializes the Mapping from a list of ':'-separated
// paths. Empty paths are ignored; relative paths are assumed
// to be relative to the current working directory and converted
// to absolute paths. For each path of the form:
//
//	dirname/localname
//
// a mapping
//
//	localname -> path
//
// is added to the Mapping object, in the order of occurrence.
// For instance, the argument:
//
//	/home/user:/home/build/public
//
// leads to the following mapping:
//
//	user   -> /home/user
//	public -> /home/build/public
//
func (m *Mapping) Init(paths string) {
	cwd, _ := os.Getwd() // ignore errors

	pathlist := strings.Split(paths, ":", 0)

	list := make([]mapping, len(pathlist))
	n := 0 // number of mappings

	for _, path := range pathlist {
		if len(path) == 0 {
			// ignore empty paths (don't assume ".")
			continue
		}

		// len(path) > 0: normalize path
		if path[0] != '/' {
			path = pathutil.Join(cwd, path)
		} else {
			path = pathutil.Clean(path)
		}

		// check if mapping exists already
		var i int
		for i = 0; i < n; i++ {
			if path == list[i].path {
				break
			}
		}

		// add mapping if it is new
		if i >= n {
			_, prefix := pathutil.Split(path)
			list[n] = mapping{prefix, path}
			n++
		}
	}

	m.list = list[0:n]
}


// IsEmpty returns true if there are no mappings specified.
func (m *Mapping) IsEmpty() bool { return len(m.list) == 0 }


// PrefixList returns a list of all prefixes, with duplicates removed.
// For instance, for the mapping:
//
//	user   -> /home/user
//	public -> /home/user/public
//	public -> /home/build/public
//
// the prefix list is:
//
//	user, public
//
func (m *Mapping) PrefixList() []string {
	// compute the list lazily
	if m.prefixes == nil {
		list := make([]string, len(m.list))
		n := 0 // nuber of prefixes

		for _, e := range m.list {
			// check if prefix exists already
			var i int
			for i = 0; i < n; i++ {
				if e.prefix == list[i] {
					break
				}
			}

			// add prefix if it is new
			if i >= n {
				list[n] = e.prefix
				n++
			}
		}
		m.prefixes = list[0:n]
	}

	return m.prefixes
}


// Fprint prints the mapping.
func (m *Mapping) Fprint(w io.Writer) {
	for _, e := range m.list {
		fmt.Fprintf(w, "\t%s -> %s\n", e.prefix, e.path)
	}
}


func split(path string) (head, tail string) {
	i := strings.Index(path, "/")
	if i > 0 {
		// 0 < i < len(path)
		return path[0:i], path[i+1:]
	}
	return "", path
}


// ToAbsolute maps a relative path to an absolute path using the Mapping
// specified by the receiver. If the path cannot be mapped, the empty
// string is returned.
//
func (m *Mapping) ToAbsolute(path string) string {
	prefix, tail := split(path)
	for _, e := range m.list {
		switch {
		case e.prefix == prefix:
			// use tail
		case e.prefix == "":
			tail = path
		default:
			continue // no match
		}
		abspath := pathutil.Join(e.path, tail)
		if _, err := os.Stat(abspath); err == nil {
			return abspath
		}
	}

	return "" // no match
}


// ToRelative maps an absolute path to a relative path using the Mapping
// specified by the receiver. If the path cannot be mapped, the empty
// string is returned.
//
func (m *Mapping) ToRelative(path string) string {
	for _, e := range m.list {
		if strings.HasPrefix(path, e.path) {
			// /absolute/prefix/foo -> prefix/foo
			return pathutil.Join(e.prefix, path[len(e.path):]) // Join will remove a trailing '/'
		}
	}
	return "" // no match
}
