// Copyright 2023 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.

package main

import (
	"io/fs"
	"log"
	"os"
	"path"
	"path/filepath"
	"sort"
	"strings"
	"time"
)

// An Archive describes an archive to write: a collection of files.
// Directories are implied by the files and not explicitly listed.
type Archive struct {
	Files []File
}

// A File describes a single file to write to an archive.
type File struct {
	Name string    // name in archive
	Time time.Time // modification time
	Mode fs.FileMode
	Size int64
	Src  string // source file in OS file system
}

// Info returns a FileInfo about the file, for use with tar.FileInfoHeader
// and zip.FileInfoHeader.
func (f *File) Info() fs.FileInfo {
	return fileInfo{f}
}

// A fileInfo is an implementation of fs.FileInfo describing a File.
type fileInfo struct {
	f *File
}

func (i fileInfo) Name() string       { return path.Base(i.f.Name) }
func (i fileInfo) ModTime() time.Time { return i.f.Time }
func (i fileInfo) Mode() fs.FileMode  { return i.f.Mode }
func (i fileInfo) IsDir() bool        { return i.f.Mode&fs.ModeDir != 0 }
func (i fileInfo) Size() int64        { return i.f.Size }
func (i fileInfo) Sys() any           { return nil }

func (i fileInfo) String() string {
	return fs.FormatFileInfo(i)
}

// NewArchive returns a new Archive containing all the files in the directory dir.
// The archive can be amended afterward using methods like Add and Filter.
func NewArchive(dir string) (*Archive, error) {
	a := new(Archive)
	err := fs.WalkDir(os.DirFS(dir), ".", func(name string, d fs.DirEntry, err error) error {
		if err != nil {
			return err
		}
		if d.IsDir() {
			return nil
		}
		info, err := d.Info()
		if err != nil {
			return err
		}
		a.Add(name, filepath.Join(dir, name), info)
		return nil
	})
	if err != nil {
		return nil, err
	}
	a.Sort()
	return a, nil
}

// Add adds a file with the given name and info to the archive.
// The content of the file comes from the operating system file src.
// After a sequence of one or more calls to Add,
// the caller should invoke Sort to re-sort the archive's files.
func (a *Archive) Add(name, src string, info fs.FileInfo) {
	a.Files = append(a.Files, File{
		Name: name,
		Time: info.ModTime(),
		Mode: info.Mode(),
		Size: info.Size(),
		Src:  src,
	})
}

// Sort sorts the files in the archive.
// It is only necessary to call Sort after calling Add or RenameGoMod.
// ArchiveDir returns a sorted archive, and the other methods
// preserve the sorting of the archive.
func (a *Archive) Sort() {
	sort.Slice(a.Files, func(i, j int) bool {
		return a.Files[i].Name < a.Files[j].Name
	})
}

// Clone returns a copy of the Archive.
// Method calls like Add and Filter invoked on the copy do not affect the original,
// nor do calls on the original affect the copy.
func (a *Archive) Clone() *Archive {
	b := &Archive{
		Files: make([]File, len(a.Files)),
	}
	copy(b.Files, a.Files)
	return b
}

// AddPrefix adds a prefix to all file names in the archive.
func (a *Archive) AddPrefix(prefix string) {
	for i := range a.Files {
		a.Files[i].Name = path.Join(prefix, a.Files[i].Name)
	}
}

// Filter removes files from the archive for which keep(name) returns false.
func (a *Archive) Filter(keep func(name string) bool) {
	files := a.Files[:0]
	for _, f := range a.Files {
		if keep(f.Name) {
			files = append(files, f)
		}
	}
	a.Files = files
}

// SetMode changes the mode of every file in the archive
// to be mode(name, m), where m is the file's current mode.
func (a *Archive) SetMode(mode func(name string, m fs.FileMode) fs.FileMode) {
	for i := range a.Files {
		a.Files[i].Mode = mode(a.Files[i].Name, a.Files[i].Mode)
	}
}

// Remove removes files matching any of the patterns from the archive.
// The patterns use the syntax of path.Match, with an extension of allowing
// a leading **/ or trailing /**, which match any number of path elements
// (including no path elements) before or after the main match.
func (a *Archive) Remove(patterns ...string) {
	a.Filter(func(name string) bool {
		for _, pattern := range patterns {
			match, err := amatch(pattern, name)
			if err != nil {
				log.Fatalf("archive remove: %v", err)
			}
			if match {
				return false
			}
		}
		return true
	})
}

// SetTime sets the modification time of all files in the archive to t.
func (a *Archive) SetTime(t time.Time) {
	for i := range a.Files {
		a.Files[i].Time = t
	}
}

// RenameGoMod renames the go.mod files in the archive to _go.mod,
// for use with the module form, which cannot contain other go.mod files.
func (a *Archive) RenameGoMod() {
	for i, f := range a.Files {
		if strings.HasSuffix(f.Name, "/go.mod") {
			a.Files[i].Name = strings.TrimSuffix(f.Name, "go.mod") + "_go.mod"
		}
	}
}

func amatch(pattern, name string) (bool, error) {
	// firstN returns the prefix of name corresponding to the first n path elements.
	// If n <= 0, firstN returns the entire name.
	firstN := func(name string, n int) string {
		for i := 0; i < len(name); i++ {
			if name[i] == '/' {
				if n--; n == 0 {
					return name[:i]
				}
			}
		}
		return name
	}

	// lastN returns the suffix of name corresponding to the last n path elements.
	// If n <= 0, lastN returns the entire name.
	lastN := func(name string, n int) string {
		for i := len(name) - 1; i >= 0; i-- {
			if name[i] == '/' {
				if n--; n == 0 {
					return name[i+1:]
				}
			}
		}
		return name
	}

	if p, ok := strings.CutPrefix(pattern, "**/"); ok {
		return path.Match(p, lastN(name, 1+strings.Count(p, "/")))
	}
	if p, ok := strings.CutSuffix(pattern, "/**"); ok {
		return path.Match(p, firstN(name, 1+strings.Count(p, "/")))
	}
	return path.Match(pattern, name)
}
