// Copyright 2021 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 modfile

import (
	"fmt"
	"sort"
	"strings"
)

// A WorkFile is the parsed, interpreted form of a go.work file.
type WorkFile struct {
	Go        *Go
	Directory []*Directory
	Replace   []*Replace

	Syntax *FileSyntax
}

// A Directory is a single directory statement.
type Directory struct {
	Path       string // Directory path of module.
	ModulePath string // Module path in the comment.
	Syntax     *Line
}

// ParseWork parses and returns a go.work file.
//
// file is the name of the file, used in positions and errors.
//
// data is the content of the file.
//
// fix is an optional function that canonicalizes module versions.
// If fix is nil, all module versions must be canonical (module.CanonicalVersion
// must return the same string).
func ParseWork(file string, data []byte, fix VersionFixer) (*WorkFile, error) {
	fs, err := parse(file, data)
	if err != nil {
		return nil, err
	}
	f := &WorkFile{
		Syntax: fs,
	}
	var errs ErrorList

	for _, x := range fs.Stmt {
		switch x := x.(type) {
		case *Line:
			f.add(&errs, x, x.Token[0], x.Token[1:], fix)

		case *LineBlock:
			if len(x.Token) > 1 {
				errs = append(errs, Error{
					Filename: file,
					Pos:      x.Start,
					Err:      fmt.Errorf("unknown block type: %s", strings.Join(x.Token, " ")),
				})
				continue
			}
			switch x.Token[0] {
			default:
				errs = append(errs, Error{
					Filename: file,
					Pos:      x.Start,
					Err:      fmt.Errorf("unknown block type: %s", strings.Join(x.Token, " ")),
				})
				continue
			case "directory", "replace":
				for _, l := range x.Line {
					f.add(&errs, l, x.Token[0], l.Token, fix)
				}
			}
		}
	}

	if len(errs) > 0 {
		return nil, errs
	}
	return f, nil
}

// Cleanup cleans up the file f after any edit operations.
// To avoid quadratic behavior, modifications like DropRequire
// clear the entry but do not remove it from the slice.
// Cleanup cleans out all the cleared entries.
func (f *WorkFile) Cleanup() {
	w := 0
	for _, r := range f.Directory {
		if r.Path != "" {
			f.Directory[w] = r
			w++
		}
	}
	f.Directory = f.Directory[:w]

	w = 0
	for _, r := range f.Replace {
		if r.Old.Path != "" {
			f.Replace[w] = r
			w++
		}
	}
	f.Replace = f.Replace[:w]

	f.Syntax.Cleanup()
}

func (f *WorkFile) AddGoStmt(version string) error {
	if !GoVersionRE.MatchString(version) {
		return fmt.Errorf("invalid language version string %q", version)
	}
	if f.Go == nil {
		stmt := &Line{Token: []string{"go", version}}
		f.Go = &Go{
			Version: version,
			Syntax:  stmt,
		}
		// Find the first non-comment-only block that's and add
		// the go statement before it. That will keep file comments at the top.
		i := 0
		for i = 0; i < len(f.Syntax.Stmt); i++ {
			if _, ok := f.Syntax.Stmt[i].(*CommentBlock); !ok {
				break
			}
		}
		f.Syntax.Stmt = append(append(f.Syntax.Stmt[:i:i], stmt), f.Syntax.Stmt[i:]...)
	} else {
		f.Go.Version = version
		f.Syntax.updateLine(f.Go.Syntax, "go", version)
	}
	return nil
}

func (f *WorkFile) AddDirectory(diskPath, modulePath string) error {
	need := true
	for _, d := range f.Directory {
		if d.Path == diskPath {
			if need {
				d.ModulePath = modulePath
				f.Syntax.updateLine(d.Syntax, "directory", AutoQuote(diskPath))
				need = false
			} else {
				d.Syntax.markRemoved()
				*d = Directory{}
			}
		}
	}

	if need {
		f.AddNewDirectory(diskPath, modulePath)
	}
	return nil
}

func (f *WorkFile) AddNewDirectory(diskPath, modulePath string) {
	line := f.Syntax.addLine(nil, "directory", AutoQuote(diskPath))
	f.Directory = append(f.Directory, &Directory{Path: diskPath, ModulePath: modulePath, Syntax: line})
}

func (f *WorkFile) SetDirectory(dirs []*Directory) {
	need := make(map[string]string)
	for _, d := range dirs {
		need[d.Path] = d.ModulePath
	}

	for _, d := range f.Directory {
		if modulePath, ok := need[d.Path]; ok {
			d.ModulePath = modulePath
		} else {
			d.Syntax.markRemoved()
			*d = Directory{}
		}
	}

	// TODO(#45713): Add module path to comment.

	for diskPath, modulePath := range need {
		f.AddNewDirectory(diskPath, modulePath)
	}
	f.SortBlocks()
}

func (f *WorkFile) DropDirectory(path string) error {
	for _, d := range f.Directory {
		if d.Path == path {
			d.Syntax.markRemoved()
			*d = Directory{}
		}
	}
	return nil
}

func (f *WorkFile) AddReplace(oldPath, oldVers, newPath, newVers string) error {
	return addReplace(f.Syntax, &f.Replace, oldPath, oldVers, newPath, newVers)
}

func (f *WorkFile) DropReplace(oldPath, oldVers string) error {
	for _, r := range f.Replace {
		if r.Old.Path == oldPath && r.Old.Version == oldVers {
			r.Syntax.markRemoved()
			*r = Replace{}
		}
	}
	return nil
}

func (f *WorkFile) SortBlocks() {
	f.removeDups() // otherwise sorting is unsafe

	for _, stmt := range f.Syntax.Stmt {
		block, ok := stmt.(*LineBlock)
		if !ok {
			continue
		}
		sort.SliceStable(block.Line, func(i, j int) bool {
			return lineLess(block.Line[i], block.Line[j])
		})
	}
}

// removeDups removes duplicate replace directives.
//
// Later replace directives take priority.
//
// require directives are not de-duplicated. That's left up to higher-level
// logic (MVS).
//
// retract directives are not de-duplicated since comments are
// meaningful, and versions may be retracted multiple times.
func (f *WorkFile) removeDups() {
	removeDups(f.Syntax, nil, &f.Replace)
}
