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

//go:build ignore
// +build ignore

//go:generate go run ./copier.go

// Copier is a tool to automate copy of govulncheck's internal files.
//
//   - copy golang.org/x/vuln/internal/osv/ to osv
//   - copy golang.org/x/vuln/internal/govulncheck/ to govulncheck
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"go/parser"
	"go/token"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strconv"
	"strings"

	"golang.org/x/tools/internal/edit"
)

func main() {
	log.SetPrefix("copier: ")
	log.SetFlags(log.Lshortfile)

	srcMod := "golang.org/x/vuln"
	srcModVers := "@latest"
	srcDir, srcVer := downloadModule(srcMod + srcModVers)

	cfg := rewrite{
		banner:        fmt.Sprintf("// Code generated by copying from %v@%v (go run copier.go); DO NOT EDIT.", srcMod, srcVer),
		srcImportPath: "golang.org/x/vuln/internal",
		dstImportPath: currentPackagePath(),
	}

	copyFiles("osv", filepath.Join(srcDir, "internal", "osv"), cfg)
	copyFiles("govulncheck", filepath.Join(srcDir, "internal", "govulncheck"), cfg)
}

type rewrite struct {
	// DO NOT EDIT marker to add at the beginning
	banner string
	// rewrite srcImportPath with dstImportPath
	srcImportPath string
	dstImportPath string
}

func copyFiles(dst, src string, cfg rewrite) {
	entries, err := os.ReadDir(src)
	if err != nil {
		log.Fatalf("failed to read dir: %v", err)
	}
	if err := os.MkdirAll(dst, 0777); err != nil {
		log.Fatalf("failed to create dir: %v", err)
	}

	for _, e := range entries {
		fname := e.Name()
		// we need only non-test go files.
		if e.IsDir() || !strings.HasSuffix(fname, ".go") || strings.HasSuffix(fname, "_test.go") {
			continue
		}
		data, err := os.ReadFile(filepath.Join(src, fname))
		if err != nil {
			log.Fatal(err)
		}
		fset := token.NewFileSet()
		f, err := parser.ParseFile(fset, fname, data, parser.ParseComments|parser.ImportsOnly)
		if err != nil {
			log.Fatalf("parsing source module:\n%s", err)
		}

		buf := edit.NewBuffer(data)
		at := func(p token.Pos) int {
			return fset.File(p).Offset(p)
		}

		// Add banner right after the copyright statement (the first comment)
		bannerInsert, banner := f.FileStart, cfg.banner
		if len(f.Comments) > 0 && strings.HasPrefix(f.Comments[0].Text(), "Copyright ") {
			bannerInsert = f.Comments[0].End()
			banner = "\n\n" + banner
		}
		buf.Replace(at(bannerInsert), at(bannerInsert), banner)

		// Adjust imports
		for _, spec := range f.Imports {
			path, err := strconv.Unquote(spec.Path.Value)
			if err != nil {
				log.Fatal(err)
			}
			if strings.HasPrefix(path, cfg.srcImportPath) {
				newPath := strings.Replace(path, cfg.srcImportPath, cfg.dstImportPath, 1)
				buf.Replace(at(spec.Path.Pos()), at(spec.Path.End()), strconv.Quote(newPath))
			}
		}
		data = buf.Bytes()

		if err := os.WriteFile(filepath.Join(dst, fname), data, 0666); err != nil {
			log.Fatal(err)
		}
	}
}

func downloadModule(srcModVers string) (dir, ver string) {
	var stdout, stderr bytes.Buffer
	cmd := exec.Command("go", "mod", "download", "-json", srcModVers)
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr
	if err := cmd.Run(); err != nil {
		log.Fatalf("go mod download -json %s: %v\n%s%s", srcModVers, err, stderr.Bytes(), stdout.Bytes())
	}
	var info struct {
		Dir     string
		Version string
	}
	if err := json.Unmarshal(stdout.Bytes(), &info); err != nil {
		log.Fatalf("go mod download -json %s: invalid JSON output: %v\n%s%s", srcModVers, err, stderr.Bytes(), stdout.Bytes())
	}
	return info.Dir, info.Version
}

func currentPackagePath() string {
	var stdout, stderr bytes.Buffer
	cmd := exec.Command("go", "list", ".")
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr
	if err := cmd.Run(); err != nil {
		log.Fatalf("go list: %v\n%s%s", err, stderr.Bytes(), stdout.Bytes())
	}
	return strings.TrimSpace(stdout.String())
}
