// Copyright 2024 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 bazel_docgen

import (
	"path/filepath"
	"sort"

	pb "go.fuchsia.dev/fuchsia/tools/bazel-docgen/third_party/stardoc"
	"golang.org/x/exp/maps"
	"gopkg.in/yaml.v2"
)

type supportedDocType int

const (
	docTypeRule = iota
	docTypeProvider
	docTypeStarlarkFunction
	docTypeRepositoryRule
)

type tocEntry struct {
	Title    string     `yaml:",omitempty"`
	Path     string     `yaml:",omitempty"`
	Heading  string     `yaml:",omitempty"`
	Sections []tocEntry `yaml:"section,omitempty"`
	docType  int
}

func newTocEntry(title string, filename string, docType int, mkPathFn func(string) string) tocEntry {
	return tocEntry{
		Title:   title,
		Path:    mkPathFn(filename),
		docType: docType,
	}
}

func checkDuplicateName(name string, entries map[string]tocEntry) bool {
	_, ok := entries[name]
	return ok
}

func filterEntries(entries []tocEntry, docType int) []tocEntry {
	var filteredEntries []tocEntry
	for _, entry := range entries {
		if entry.docType == docType {
			filteredEntries = append(filteredEntries, entry)
		}
	}

	sort.Slice(filteredEntries, func(i, j int) bool {
		return filteredEntries[i].Title < filteredEntries[j].Title
	})
	return filteredEntries
}

func RenderModuleInfo(roots []pb.ModuleInfo, renderer Renderer, fileProvider FileProvider, basePath string) {
	fileProvider.Open()

	mkPathFn := func(s string) string {
		return filepath.Join("/", basePath, s)
	}

	entries := make(map[string]tocEntry)

	for _, moduleInfo := range roots {

		// Render all of our rules
		for _, rule := range moduleInfo.GetRuleInfo() {
			fileName := "rule_" + rule.RuleName + ".md"
			if checkDuplicateName(fileName, entries) {
				continue
			}
			if err := renderer.RenderRuleInfo(rule, fileProvider.NewFile(fileName)); err != nil {
				panic(err)
			}
			entries[fileName] = newTocEntry(rule.RuleName, fileName, docTypeRule, mkPathFn)
		}

		// Render all of our providers
		for _, provider := range moduleInfo.GetProviderInfo() {
			fileName := "provider_" + provider.ProviderName + ".md"
			checkDuplicateName(fileName, entries)
			if err := renderer.RenderProviderInfo(provider, fileProvider.NewFile(fileName)); err != nil {
				panic(err)
			}
			entries[fileName] = newTocEntry(provider.ProviderName, fileName, docTypeProvider, mkPathFn)
		}

		// Render all of our starlark functions
		for _, funcInfo := range moduleInfo.GetFuncInfo() {
			fileName := "func_" + funcInfo.FunctionName + ".md"
			checkDuplicateName(fileName, entries)
			if err := renderer.RenderStarlarkFunctionInfo(funcInfo, fileProvider.NewFile(fileName)); err != nil {
				panic(err)
			}
			entries[fileName] = newTocEntry(funcInfo.FunctionName, fileName, docTypeStarlarkFunction, mkPathFn)
		}

		// Render all of our rules
		for _, repoRule := range moduleInfo.GetRepositoryRuleInfo() {
			fileName := "repo_rule_" + repoRule.RuleName + ".md"
			checkDuplicateName(fileName, entries)
			if err := renderer.RenderRepositoryRuleInfo(repoRule, fileProvider.NewFile(fileName)); err != nil {
				panic(err)
			}
			entries[fileName] = newTocEntry(repoRule.RuleName, fileName, docTypeRepositoryRule, mkPathFn)
		}
	}

	// Render our README.md
	readmeWriter := fileProvider.NewFile("README.md")
	readmeWriter.Write([]byte(""))

	tocEntries := maps.Values(entries)
	toc := []tocEntry{
		{
			Title: "Overview",
			Path:  mkPathFn("README.md"),
		},
		{
			Title: "API",
			Sections: []tocEntry{
				{
					Title:    "Rules",
					Sections: filterEntries(tocEntries, docTypeRule),
				},
				{
					Title:    "Providers",
					Sections: filterEntries(tocEntries, docTypeProvider),
				},
				{
					Title:    "Starlark Functions",
					Sections: filterEntries(tocEntries, docTypeStarlarkFunction),
				},
				{
					Title:    "Repository Rules",
					Sections: filterEntries(tocEntries, docTypeRepositoryRule),
				},
			},
		},
	}

	// Make our table of contents
	if yamlData, err := yaml.Marshal(&map[string]interface{}{"toc": toc}); err == nil {
		tocWriter := fileProvider.NewFile("_toc.yaml")
		tocWriter.Write(yamlData)
	}

	fileProvider.Close()
}
