package archive

import (
	"strings"
)

// Resolve parses the .archive request filename and returns the server-relative
// path (no leading slash) of the resolved file within the named project. The
// caller serves that file in place — the .archive URL is intentionally stable
// across revisions so external links like .archive/<tracking>.html#section
// keep tracking the latest copy without exposing the per-transmittal URL.
//
// Project is the top-level segment of the .archive contextPath
// (/<project>/.../.archive/<filename>). An empty project — i.e. a request
// against /.archive/ at the very root — returns ("", false): stable refs
// must be project-rooted to avoid cross-project tracking-number collisions.
//
// Supported URL filename patterns (after stripping .html suffix):
//   - trackingNumber              → highest base revision of trackingNumber
//   - trackingNumber_rev          → base revision file for rev
//   - trackingNumber_rev+C1       → modifier file (C1, B1, N1, Q1)
//
// Returns ("", false) if project is empty, the filename cannot be parsed, or
// no match exists in the project.
func Resolve(idx *Index, project, filename string) (string, bool) {
	if project == "" {
		return "", false
	}

	// Strip .html suffix
	stem := strings.TrimSuffix(filename, ".html")
	if stem == filename {
		// No .html suffix — not a valid archive request
		return "", false
	}

	idx.mu.RLock()
	defer idx.mu.RUnlock()

	pe, ok := idx.ByProject[project]
	if !ok {
		return "", false
	}

	// Try to split off revision part (last _ segment)
	lastUnderscore := strings.LastIndex(stem, "_")
	if lastUnderscore < 0 {
		// No underscore — treat entire stem as tracking number
		tracking := stem
		te, ok := pe.ByTracking[tracking]
		if !ok || te.HighestBaseRev == "" {
			return "", false
		}
		re, ok := te.ByRevision[te.HighestBaseRev]
		if !ok || re.BasePath == "" {
			return "", false
		}
		return re.BasePath, true
	}

	tracking := stem[:lastUnderscore]
	revPart := stem[lastUnderscore+1:]

	// Split revPart on "+" to separate baseRev from modifier
	plusIdx := strings.Index(revPart, "+")
	var baseRev, modifier string
	if plusIdx < 0 {
		baseRev = revPart
		modifier = ""
	} else {
		baseRev = revPart[:plusIdx]
		modifier = revPart[plusIdx+1:]
	}

	te, ok := pe.ByTracking[tracking]
	if !ok {
		return "", false
	}

	re, ok := te.ByRevision[baseRev]
	if !ok {
		return "", false
	}

	if modifier == "" {
		if re.BasePath == "" {
			return "", false
		}
		return re.BasePath, true
	}

	// Modifier lookup
	path, ok := re.Modifiers[modifier]
	if !ok {
		return "", false
	}
	return path, true
}
