// Copyright 2022 The Fuchsia 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 (
	"archive/zip"
	"flag"
	"io"
	"log"
	"os"
	"path/filepath"
	"sort"
	"strings"

	"go.fuchsia.dev/fuchsia/tools/cppdocgen/clangdoc"
	"go.fuchsia.dev/fuchsia/tools/cppdocgen/docgen"
)

var flags struct {
	inDir        string
	inZip        string
	outDir       string
	outZip       string
	libName      string
	sourceRoot   string
	buildDir     string
	includeDir   string
	repoBaseUrl  string
	tocPath      string
	overviewFile string
}

func init() {
	flag.StringVar(&flags.inDir, "in-dir", "", "Input directory")
	flag.StringVar(&flags.inZip, "in-zip", "", "Input zip file")
	flag.StringVar(&flags.outDir, "out-dir", "", "Output directory")
	flag.StringVar(&flags.outZip, "out-zip", "", "Output zip file")
	flag.StringVar(&flags.libName, "lib-name", "", "User-visible library name")
	flag.StringVar(&flags.sourceRoot, "source-root", "", "Repository root directory.")
	flag.StringVar(&flags.buildDir, "build-dir", "",
		"Build directory from whence clang-doc paths are relative.")
	flag.StringVar(&flags.includeDir, "include-dir", "",
		"The directory where #includes are relative to (used for generating titles and #include examples).")
	flag.StringVar(&flags.repoBaseUrl, "source-url", "",
		"URL of code repo for paths will be appended to for generating source links.")
	flag.StringVar(&flags.tocPath, "toc-path", "",
		"Absolute path on devsite where this code will be hosted, for paths in _toc.yaml.")
	flag.StringVar(&flags.overviewFile, "overview", "",
		"Path of the file that will comprise the top of the index.")
}

func main() {
	log.SetPrefix("cppdocgen: ")
	flag.Parse()
	if len(flags.repoBaseUrl) == 0 {
		log.Fatal("No repo base URL (-u) specified")
	}
	if !strings.HasSuffix(flags.repoBaseUrl, "/") {
		// The base URL should always end in a slash for appending file paths.
		flags.repoBaseUrl += "/"
	}

	if len(flags.libName) == 0 {
		log.Fatal("No library name (--lib-name) specified")
	}
	if len(flags.sourceRoot) == 0 {
		log.Fatal("No respository source root (--source-root) specified")
	}
	if len(flags.buildDir) == 0 {
		log.Fatal("No build directory (--build-dir) specified")
	}
	if len(flags.includeDir) == 0 {
		log.Fatal("No include directory (--include-dir) specified")
	}

	tocPath := flags.tocPath
	if len(tocPath) == 0 {
		log.Fatal("No --toc-path specified")
	}
	if !strings.HasSuffix(tocPath, "/") {
		tocPath += "/"
	}

	var overviewContents []byte
	if flags.overviewFile != "" {
		inContents, err := os.ReadFile(flags.overviewFile)
		if err != nil {
			log.Fatal(err)
		}
		overviewContents = inContents
	}

	buildRelSourceRoot, err := filepath.Rel(flags.buildDir, flags.sourceRoot)
	if err != nil {
		log.Fatal("Can't rebase source root: %s", err)
	}
	buildRelIncludeDir, err := filepath.Rel(flags.buildDir, flags.includeDir)
	if err != nil {
		log.Fatal("Can't rebase include dir: %s", err)
	}
	writeSettings := docgen.WriteSettings{
		LibName:            flags.libName,
		BuildRelSourceRoot: buildRelSourceRoot,
		BuildRelIncludeDir: buildRelIncludeDir,
		RepoBaseUrl:        flags.repoBaseUrl,
		TocPath:            tocPath,
		OverviewContents:   overviewContents,
	}

	// All other args are the list of headers we want to index.
	indexSettings := docgen.MakeIndexSettings(flags.buildDir)
	for _, a := range flag.Args() {
		indexSettings.Headers[a] = struct{}{}
	}

	// Validate input flags.
	if flags.inZip != "" && flags.inDir != "" {
		log.Fatal("Can't specify both --in-dir and --in-zip")
	} else if flags.inZip == "" && flags.inDir == "" {
		log.Fatal("Must specify either --in-dir=<dir> or --in-zip=<filename>.zip")
	}

	// Validate output flags.
	if flags.outZip != "" && flags.outDir != "" {
		log.Fatal("Can't specify both --out-dir and --out-zip")
	} else if flags.outZip == "" && flags.outDir == "" {
		log.Fatal("Must specify either --out-dir=<dir> or --out-zip=<filename>.zip")
	}

	// Set up output. The addFile() lambda will create the given file in the output format
	// requested.
	var addFile func(string) io.Writer
	if len(flags.outZip) != 0 {
		// Create a zip file.
		zipFile, err := os.Create(flags.outZip)
		if err != nil {
			log.Fatal("Can't create output file '%s':\n%v", flags.outZip, err)
		}
		defer zipFile.Close()

		zipWriter := zip.NewWriter(zipFile)
		defer zipWriter.Close()

		addFile = func(path string) io.Writer {
			file, err := zipWriter.Create(path)
			if err != nil {
				log.Fatal("Can't add '%s' to zip file\n%v", path, err)
			}
			return file
		}
	} else {
		// Create a directory.
		err := os.MkdirAll(flags.outDir, 0o755)
		if err != nil {
			log.Fatal("Can't create output directory '%s':\n%v", flags.outDir, err)
		}
		addFile = func(name string) io.Writer {
			file, err := os.Create(flags.outDir + "/" + name)
			if err != nil {
				log.Fatal(err)
			}
			return file
		}
	}

	var root *clangdoc.NamespaceInfo
	if flags.inDir != "" {
		root = clangdoc.LoadDir(flags.inDir)
	} else {
		root = clangdoc.LoadZip(flags.inZip)
	}

	index := docgen.MakeIndex(indexSettings, root)
	indexFile := addFile("index.md")
	docgen.WriteIndex(writeSettings, &index, indexFile)
	tocFile := addFile("_toc.yaml")
	docgen.WriteToc(writeSettings, &index, tocFile)

	// Header references.
	// Sort them for deterministic outputs.
	sorted_headers := make([]string, 0, len(index.Headers))
	for header := range index.Headers {
		sorted_headers = append(sorted_headers, header)
	}

	sort.Strings(sorted_headers)

	for _, header_name := range sorted_headers {
		h := index.Headers[header_name]
		n := h.ReferenceFileName()
		headerFile := addFile(n)
		docgen.WriteHeaderReference(writeSettings, &index, h, headerFile)
	}
}
