// Copyright 2015 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 gen contains common code for the various code generation tools in the
// text repository. Its usage ensures consistency between tools.
//
// This package defines command line flags that are common to most generation
// tools. The flags allow for specifying specific Unicode and CLDR versions
// in the public Unicode data repository (https://www.unicode.org/Public).
//
// A local Unicode data mirror can be set through the flag -local or the
// environment variable UNICODE_DIR. The former takes precedence. The local
// directory should follow the same structure as the public repository.
//
// IANA data can also optionally be mirrored by putting it in the iana directory
// rooted at the top of the local mirror. Beware, though, that IANA data is not
// versioned. So it is up to the developer to use the right version.
package gen // import "golang.org/x/text/internal/gen"

import (
	"bytes"
	"flag"
	"fmt"
	"go/build"
	"go/format"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path"
	"path/filepath"
	"regexp"
	"strings"
	"sync"
	"unicode"

	"golang.org/x/text/unicode/cldr"
)

var (
	url = flag.String("url",
		"https://www.unicode.org/Public",
		"URL of Unicode database directory")
	iana = flag.String("iana",
		"http://www.iana.org",
		"URL of the IANA repository")
	unicodeVersion = flag.String("unicode",
		getEnv("UNICODE_VERSION", unicode.Version),
		"unicode version to use")
	cldrVersion = flag.String("cldr",
		getEnv("CLDR_VERSION", cldr.Version),
		"cldr version to use")
)

func getEnv(name, def string) string {
	if v := os.Getenv(name); v != "" {
		return v
	}
	return def
}

// Init performs common initialization for a gen command. It parses the flags
// and sets up the standard logging parameters.
func Init() {
	log.SetPrefix("")
	log.SetFlags(log.Lshortfile)
	flag.Parse()
}

const header = `// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.

`

// UnicodeVersion reports the requested Unicode version.
func UnicodeVersion() string {
	return *unicodeVersion
}

// CLDRVersion reports the requested CLDR version.
func CLDRVersion() string {
	return *cldrVersion
}

var tags = []struct{ version, buildTags string }{
	{"9.0.0", "!go1.10"},
	{"10.0.0", "go1.10,!go1.13"},
	{"11.0.0", "go1.13,!go1.14"},
	{"12.0.0", "go1.14,!go1.16"},
	{"13.0.0", "go1.16"},
}

// buildTags reports the build tags used for the current Unicode version.
func buildTags() string {
	v := UnicodeVersion()
	for _, e := range tags {
		if e.version == v {
			return e.buildTags
		}
	}
	log.Fatalf("Unknown build tags for Unicode version %q.", v)
	return ""
}

// IsLocal reports whether data files are available locally.
func IsLocal() bool {
	dir, err := localReadmeFile()
	if err != nil {
		return false
	}
	if _, err = os.Stat(dir); err != nil {
		return false
	}
	return true
}

// OpenUCDFile opens the requested UCD file. The file is specified relative to
// the public Unicode root directory. It will call log.Fatal if there are any
// errors.
func OpenUCDFile(file string) io.ReadCloser {
	return openUnicode(path.Join(*unicodeVersion, "ucd", file))
}

// OpenCLDRCoreZip opens the CLDR core zip file. It will call log.Fatal if there
// are any errors.
func OpenCLDRCoreZip() io.ReadCloser {
	return OpenUnicodeFile("cldr", *cldrVersion, "core.zip")
}

// OpenUnicodeFile opens the requested file of the requested category from the
// root of the Unicode data archive. The file is specified relative to the
// public Unicode root directory. If version is "", it will use the default
// Unicode version. It will call log.Fatal if there are any errors.
func OpenUnicodeFile(category, version, file string) io.ReadCloser {
	if version == "" {
		version = UnicodeVersion()
	}
	return openUnicode(path.Join(category, version, file))
}

// OpenIANAFile opens the requested IANA file. The file is specified relative
// to the IANA root, which is typically either http://www.iana.org or the
// iana directory in the local mirror. It will call log.Fatal if there are any
// errors.
func OpenIANAFile(path string) io.ReadCloser {
	return Open(*iana, "iana", path)
}

var (
	dirMutex sync.Mutex
	localDir string
)

const permissions = 0755

func localReadmeFile() (string, error) {
	p, err := build.Import("golang.org/x/text", "", build.FindOnly)
	if err != nil {
		return "", fmt.Errorf("Could not locate package: %v", err)
	}
	return filepath.Join(p.Dir, "DATA", "README"), nil
}

func getLocalDir() string {
	dirMutex.Lock()
	defer dirMutex.Unlock()

	readme, err := localReadmeFile()
	if err != nil {
		log.Fatal(err)
	}
	dir := filepath.Dir(readme)
	if _, err := os.Stat(readme); err != nil {
		if err := os.MkdirAll(dir, permissions); err != nil {
			log.Fatalf("Could not create directory: %v", err)
		}
		ioutil.WriteFile(readme, []byte(readmeTxt), permissions)
	}
	return dir
}

const readmeTxt = `Generated by golang.org/x/text/internal/gen. DO NOT EDIT.

This directory contains downloaded files used to generate the various tables
in the golang.org/x/text subrepo.

Note that the language subtag repo (iana/assignments/language-subtag-registry)
and all other times in the iana subdirectory are not versioned and will need
to be periodically manually updated. The easiest way to do this is to remove
the entire iana directory. This is mostly of concern when updating the language
package.
`

// Open opens subdir/path if a local directory is specified and the file exists,
// where subdir is a directory relative to the local root, or fetches it from
// urlRoot/path otherwise. It will call log.Fatal if there are any errors.
func Open(urlRoot, subdir, path string) io.ReadCloser {
	file := filepath.Join(getLocalDir(), subdir, filepath.FromSlash(path))
	return open(file, urlRoot, path)
}

func openUnicode(path string) io.ReadCloser {
	file := filepath.Join(getLocalDir(), filepath.FromSlash(path))
	return open(file, *url, path)
}

// TODO: automatically periodically update non-versioned files.

func open(file, urlRoot, path string) io.ReadCloser {
	if f, err := os.Open(file); err == nil {
		return f
	}
	r := get(urlRoot, path)
	defer r.Close()
	b, err := ioutil.ReadAll(r)
	if err != nil {
		log.Fatalf("Could not download file: %v", err)
	}
	os.MkdirAll(filepath.Dir(file), permissions)
	if err := ioutil.WriteFile(file, b, permissions); err != nil {
		log.Fatalf("Could not create file: %v", err)
	}
	return ioutil.NopCloser(bytes.NewReader(b))
}

func get(root, path string) io.ReadCloser {
	url := root + "/" + path
	fmt.Printf("Fetching %s...", url)
	defer fmt.Println(" done.")
	resp, err := http.Get(url)
	if err != nil {
		log.Fatalf("HTTP GET: %v", err)
	}
	if resp.StatusCode != 200 {
		log.Fatalf("Bad GET status for %q: %q", url, resp.Status)
	}
	return resp.Body
}

// TODO: use Write*Version in all applicable packages.

// WriteUnicodeVersion writes a constant for the Unicode version from which the
// tables are generated.
func WriteUnicodeVersion(w io.Writer) {
	fmt.Fprintf(w, "// UnicodeVersion is the Unicode version from which the tables in this package are derived.\n")
	fmt.Fprintf(w, "const UnicodeVersion = %q\n\n", UnicodeVersion())
}

// WriteCLDRVersion writes a constant for the CLDR version from which the
// tables are generated.
func WriteCLDRVersion(w io.Writer) {
	fmt.Fprintf(w, "// CLDRVersion is the CLDR version from which the tables in this package are derived.\n")
	fmt.Fprintf(w, "const CLDRVersion = %q\n\n", CLDRVersion())
}

// WriteGoFile prepends a standard file comment and package statement to the
// given bytes, applies gofmt, and writes them to a file with the given name.
// It will call log.Fatal if there are any errors.
func WriteGoFile(filename, pkg string, b []byte) {
	w, err := os.Create(filename)
	if err != nil {
		log.Fatalf("Could not create file %s: %v", filename, err)
	}
	defer w.Close()
	if _, err = WriteGo(w, pkg, "", b); err != nil {
		log.Fatalf("Error writing file %s: %v", filename, err)
	}
}

func fileToPattern(filename string) string {
	suffix := ".go"
	if strings.HasSuffix(filename, "_test.go") {
		suffix = "_test.go"
	}
	prefix := filename[:len(filename)-len(suffix)]
	return fmt.Sprint(prefix, "%s", suffix)
}

func updateBuildTags(pattern string) {
	for _, t := range tags {
		oldFile := fmt.Sprintf(pattern, t.version)
		b, err := ioutil.ReadFile(oldFile)
		if err != nil {
			continue
		}
		build := fmt.Sprintf("// +build %s", t.buildTags)
		b = regexp.MustCompile(`// \+build .*`).ReplaceAll(b, []byte(build))
		err = ioutil.WriteFile(oldFile, b, 0644)
		if err != nil {
			log.Fatal(err)
		}
	}
}

// WriteVersionedGoFile prepends a standard file comment, adds build tags to
// version the file for the current Unicode version, and package statement to
// the given bytes, applies gofmt, and writes them to a file with the given
// name. It will call log.Fatal if there are any errors.
func WriteVersionedGoFile(filename, pkg string, b []byte) {
	pattern := fileToPattern(filename)
	updateBuildTags(pattern)
	filename = fmt.Sprintf(pattern, UnicodeVersion())

	w, err := os.Create(filename)
	if err != nil {
		log.Fatalf("Could not create file %s: %v", filename, err)
	}
	defer w.Close()
	if _, err = WriteGo(w, pkg, buildTags(), b); err != nil {
		log.Fatalf("Error writing file %s: %v", filename, err)
	}
}

// WriteGo prepends a standard file comment and package statement to the given
// bytes, applies gofmt, and writes them to w.
func WriteGo(w io.Writer, pkg, tags string, b []byte) (n int, err error) {
	src := []byte(header)
	if tags != "" {
		src = append(src, fmt.Sprintf("// +build %s\n\n", tags)...)
	}
	src = append(src, fmt.Sprintf("package %s\n\n", pkg)...)
	src = append(src, b...)
	formatted, err := format.Source(src)
	if err != nil {
		// Print the generated code even in case of an error so that the
		// returned error can be meaningfully interpreted.
		n, _ = w.Write(src)
		return n, err
	}
	return w.Write(formatted)
}

// Repackage rewrites a Go file from belonging to package main to belonging to
// the given package.
func Repackage(inFile, outFile, pkg string) {
	src, err := ioutil.ReadFile(inFile)
	if err != nil {
		log.Fatalf("reading %s: %v", inFile, err)
	}
	const toDelete = "package main\n\n"
	i := bytes.Index(src, []byte(toDelete))
	if i < 0 {
		log.Fatalf("Could not find %q in %s.", toDelete, inFile)
	}
	w := &bytes.Buffer{}
	w.Write(src[i+len(toDelete):])
	WriteGoFile(outFile, pkg, w.Bytes())
}
