// Copyright 2022 Google LLC
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package exporter

import (
	"bytes"
	"fmt"
	"path/filepath"
	"strings"

	"go.skia.org/infra/go/skerr"
	"go.skia.org/skia/bazel/exporter/build_proto/analysis_v2"
	"go.skia.org/skia/bazel/exporter/build_proto/build"
	"go.skia.org/skia/bazel/exporter/interfaces"
	"google.golang.org/protobuf/proto"
)

type CMakeExporter struct {
	workspace    cmakeWorkspace
	workspaceDir string
}

// NewCMakeExporter creates an exporter that will export to the
// CMake project file format.
func NewCMakeExporter(workspaceDir string) *CMakeExporter {
	return &CMakeExporter{
		workspace:    *newCMakeWorkspace(),
		workspaceDir: workspaceDir,
	}
}

// Return the default copts (COMPILE_FLAGS in CMake) for the macOS toolchain.
func getMacPlatformRuleCopts() []string {
	// TODO(crbug.com/skia/13586): Retrieve these values from Bazel.
	// These values must match those values defined in mac_toolchain_config.bzl
	return []string{
		// These items are from _make_default_flags().
		"-std=c++17",
		"-Wno-psabi",

		// From _make_target_specific_flags.
		"--target=arm64-apple-macos11",
	}
}

// Return the default copts (COMPILE_FLAGS in CMake) for the Linux toolchain.
func getLinuxPlatformRuleCopts() []string {
	// TODO(crbug.com/skia/13586): Retrieve these values from Bazel.
	return []string{
		// These items are from _make_default_flags().
		"-std=c++17",
		"-Wno-psabi",

		// Added to avoid compile warning.
		"-Wno-attributes",
	}
}

// Write the CMake project config to set the COMPILE_FLAGS
// variables for all platforms.
func writePlatformCompileFlags(writer interfaces.Writer) {
	val := strings.Join(getMacPlatformRuleCopts(), " ")
	fmt.Fprintf(writer, "set(DEFAULT_COMPILE_FLAGS_MACOS %q)\n", val)

	val = strings.Join(getLinuxPlatformRuleCopts(), " ")
	fmt.Fprintf(writer, "set(DEFAULT_COMPILE_FLAGS_LINUX %q)\n", val)
	writer.WriteString("\n")
	fmt.Fprintln(writer, `if (APPLE)`)
	fmt.Fprintln(writer, `  set(DEFAULT_COMPILE_FLAGS "${DEFAULT_COMPILE_FLAGS_MACOS}")`)
	fmt.Fprintln(writer, `else()`)
	fmt.Fprintln(writer, `  set(DEFAULT_COMPILE_FLAGS "${DEFAULT_COMPILE_FLAGS_LINUX}")`)
	fmt.Fprintln(writer, `endif()`)
}

// Return the copts rule attribute for the given rule.
func getRuleCopts(r *build.Rule) ([]string, error) {
	ruleOpts, err := getRuleStringArrayAttribute(r, "copts")
	if err != nil {
		return nil, skerr.Wrap(err)
	}
	copts := []string{"${DEFAULT_COMPILE_FLAGS}"}
	return appendUnique(copts, ruleOpts...), nil
}

// Return the include paths for the supplied rule and all rules on which
// this rule depends.
//
// Note: All rules are absolute paths.
func getRuleIncludes(r *build.Rule, qr *analysis_v2.CqueryResult) ([]string, error) {
	deps, err := getRuleStringArrayAttribute(r, "deps")
	if err != nil {
		return nil, skerr.Wrap(err)
	}
	includes, err := getRuleStringArrayAttribute(r, "includes")
	if err != nil {
		return nil, skerr.Wrap(err)
	}
	ruleDir, err := getLocationDir(r.GetLocation())
	if err != nil {
		return nil, skerr.Wrap(err)
	}
	for idx, inc := range includes {
		if inc == "." {
			includes[idx] = ruleDir
		}
	}
	for _, d := range deps {
		dr := findRule(qr, d)
		if dr == nil {
			return nil, skerr.Fmt("cannot find rule %s", d)
		}
		if isExternalRule(dr.GetName()) {
			continue
		}
		incs, err := getRuleIncludes(dr, qr)
		if err != nil {
			return nil, skerr.Wrap(err)
		}
		includes = appendUnique(includes, incs...)
	}
	return includes, nil
}

// Return the deps for the supplied rule and all rules on which
// this rule depends.
func getRuleDefines(r *build.Rule, qr *analysis_v2.CqueryResult) ([]string, error) {
	deps, err := getRuleStringArrayAttribute(r, "deps")
	if err != nil {
		return nil, skerr.Wrap(err)
	}
	defines, err := getRuleStringArrayAttribute(r, "defines")
	if err != nil {
		return nil, skerr.Wrap(err)
	}
	for _, d := range deps {
		dr := findRule(qr, d)
		if dr == nil {
			return nil, skerr.Fmt("cannot find rule %s", d)
		}
		defs, err := getRuleDefines(dr, qr)
		if err != nil {
			return nil, skerr.Wrap(err)
		}
		defines = appendUnique(defines, defs...)
	}
	return defines, nil
}

// Convert an absolute path to a file *within the workspace* to a
// workspace relative path. All paths start with ${CMAKE_SOURCE_DIR}.
func (e *CMakeExporter) absToWorkspaceRelativePath(absPath string) string {
	if absPath == e.workspaceDir {
		return "${CMAKE_SOURCE_DIR}"
	}
	return fmt.Sprintf("${CMAKE_SOURCE_DIR}/%s", absPath[len(e.workspaceDir)+1:])
}

// Write the list of items (which may be rules or files) to the supplied buffer.
func (e *CMakeExporter) writeItems(r *cmakeRule, projectDir string, items []string, buffer *bytes.Buffer) error {
	for _, item := range items {
		if isFileTarget(item) {
			_, _, target, err := parseRule(item)
			if err != nil {
				return skerr.Wrap(err)
			}
			absPath := filepath.Join(projectDir, target)
			fmt.Fprintf(buffer, "    %q\n", e.absToWorkspaceRelativePath(absPath))
		} else {
			cmakeName, err := getRuleSimpleName(item)
			if err != nil {
				return skerr.Wrap(err)
			}
			fmt.Fprintf(buffer, "    ${%s}\n", cmakeName)
			err = r.addDependency(item)
			if err != nil {
				return skerr.Wrap(err)
			}
		}
	}
	return nil
}

// Write the "srcs" and "hdrs" rule attributes to the supplied buffer.
func (e *CMakeExporter) writeSrcsAndHdrs(rule *cmakeRule, buffer *bytes.Buffer, r *build.Rule) error {
	ruleDir, err := getLocationDir(r.GetLocation())
	if err != nil {
		return skerr.Wrap(err)
	}
	for _, attrib := range r.Attribute {
		if attrib.GetName() == "srcs" {
			if attrib.GetType() != build.Attribute_LABEL_LIST {
				return skerr.Fmt(`srcs in rule %q is not a list`, r.GetName())
			}
			fmt.Fprintln(buffer, "    # Sources:")
			err := e.writeItems(rule, ruleDir, attrib.GetStringListValue(), buffer)
			if err != nil {
				return skerr.Wrap(err)
			}
		}
		if attrib.GetName() == "hdrs" {
			if attrib.GetType() != build.Attribute_LABEL_LIST {
				return skerr.Fmt(`hdrs in rule %q is not a list`, r.GetName())
			}
			fmt.Fprintln(buffer, "    # Headers:")
			err := e.writeItems(rule, ruleDir, attrib.GetStringListValue(), buffer)
			if err != nil {
				return skerr.Wrap(err)
			}
		}
	}
	return nil
}

// Write the target COMPILE_FLAGS property to the supplied buffer (if there are any copts).
func (e *CMakeExporter) writeCompileFlags(r *build.Rule, buffer *bytes.Buffer) error {
	copts, err := getRuleCopts(r)
	if err != nil {
		return skerr.Wrap(err)
	}
	if len(copts) == 0 {
		// No error, just nothing to write.
		return nil
	}
	str := strings.Join(copts, " ")
	cmakeName, err := getRuleSimpleName(r.GetName())
	if err != nil {
		return skerr.Wrap(err)
	}
	_, err = fmt.Fprintf(buffer, "set_target_properties(%s PROPERTIES COMPILE_FLAGS\n  %q\n)\n",
		cmakeName, str)
	return err
}

// Write the target COMPILE_DEFINITIONS property to the supplied buffer (if there are any defines).
func (e *CMakeExporter) writeCompileDefinitions(r *build.Rule, qr *analysis_v2.CqueryResult, buffer *bytes.Buffer) error {
	defines, err := getRuleDefines(r, qr)
	if err != nil {
		return skerr.Wrap(err)
	}
	if len(defines) == 0 {
		// No error, just nothing to write.
		return nil
	}
	str := strings.Join(defines, ";")
	cmakeName, err := getRuleSimpleName(r.GetName())
	if err != nil {
		return skerr.Wrap(err)
	}
	_, err = fmt.Fprintf(buffer, "set_target_properties(%s PROPERTIES COMPILE_DEFINITIONS\n  %q\n)\n", cmakeName, str)
	return err
}

// Write the target INCLUDE_DIRECTORIES property to the supplied buffer (if there are any).
func (e *CMakeExporter) writeIncludeDirectories(r *build.Rule, qr *analysis_v2.CqueryResult, buffer *bytes.Buffer) error {
	includes, err := getRuleIncludes(r, qr)
	if err != nil {
		return skerr.Wrap(err)
	}
	includes = appendUnique(includes, e.workspaceDir)
	for i, path := range includes {
		includes[i] = e.absToWorkspaceRelativePath(path)
	}
	str := strings.Join(includes, ";")
	cmakeName, err := getRuleSimpleName(r.GetName())
	if err != nil {
		return skerr.Wrap(err)
	}
	_, err = fmt.Fprintf(buffer, "set_target_properties(%s PROPERTIES INCLUDE_DIRECTORIES\n  %q\n)\n", cmakeName, str)
	return err
}

// Write the target LINK_FLAGS property to the supplied buffer (if there are any linkopts).
func (e *CMakeExporter) writeLinkFlags(r *build.Rule, buffer *bytes.Buffer) error {
	defines, err := getRuleStringArrayAttribute(r, "linkopts")
	if err != nil {
		return skerr.Wrap(err)
	}
	if len(defines) == 0 {
		// No error, just nothing to write.
		return nil
	}
	str := strings.Join(defines, " ")
	cmakeName, err := getRuleSimpleName(r.GetName())
	if err != nil {
		return skerr.Wrap(err)
	}
	_, err = fmt.Fprintf(buffer, "set_target_properties(%s PROPERTIES LINK_FLAGS\n  %q\n)\n", cmakeName, str)
	return err
}

// Write all target properties to the supplied buffer.
func (e *CMakeExporter) writeProperties(r *build.Rule, qr *analysis_v2.CqueryResult, buffer *bytes.Buffer) error {
	err := e.writeCompileFlags(r, buffer)
	if err != nil {
		return skerr.Wrap(err)
	}
	err = e.writeLinkFlags(r, buffer)
	if err != nil {
		return skerr.Wrap(err)
	}
	err = e.writeCompileDefinitions(r, qr, buffer)
	if err != nil {
		return skerr.Wrap(err)
	}
	err = e.writeIncludeDirectories(r, qr, buffer)
	if err != nil {
		return skerr.Wrap(err)
	}
	return nil
}

// Convert the filegroup rule to the CMake equivalent.
func (e *CMakeExporter) convertFilegroupRule(r *build.Rule) error {

	rule := e.workspace.createRule(r)

	var contents bytes.Buffer

	targetName := r.GetName()
	variableName, err := getRuleSimpleName(r.GetName())
	if err != nil {
		return skerr.Wrap(err)
	}
	fmt.Fprintf(&contents, "# %s\n", targetName)
	fmt.Fprintf(&contents, "list(APPEND %s\n", variableName)

	err = e.writeSrcsAndHdrs(rule, &contents, r)
	if err != nil {
		return skerr.Wrap(err)
	}
	fmt.Fprintln(&contents, ")")
	rule.setContents(contents.Bytes())

	return nil
}

// Convert the cc_binary rule to the CMake equivalent.
func (e *CMakeExporter) convertCCBinaryRule(r *build.Rule, qr *analysis_v2.CqueryResult) error {

	rule := e.workspace.createRule(r)

	targetName := r.GetName()
	var contents bytes.Buffer
	fmt.Fprintf(&contents, "# %s\n", targetName)
	cmakeName, err := getRuleSimpleName(r.GetName())
	if err != nil {
		return skerr.Wrap(err)
	}
	fmt.Fprintf(&contents, "add_executable(%s \"\")\n", cmakeName)
	fmt.Fprintf(&contents, "target_sources(%s\n", cmakeName)
	fmt.Fprintln(&contents, "  PRIVATE")

	err = e.writeSrcsAndHdrs(rule, &contents, r)
	if err != nil {
		return skerr.Wrap(err)
	}

	fmt.Fprintln(&contents, ")")
	err = e.writeProperties(r, qr, &contents)
	if err != nil {
		return skerr.Wrap(err)
	}
	rule.setContents(contents.Bytes())

	return nil
}

// Convert the cc_library rule to the CMake equivalent.
func (e *CMakeExporter) convertCCLibraryRule(r *build.Rule, qr *analysis_v2.CqueryResult) error {

	rule := e.workspace.createRule(r)

	targetName := r.GetName()
	cmakeName, err := getRuleSimpleName(r.GetName())
	if err != nil {
		return skerr.Wrap(err)
	}
	var contents bytes.Buffer
	fmt.Fprintf(&contents, "# %s\n", targetName)
	fmt.Fprintf(&contents, "add_library(%s \"\")\n", cmakeName)
	fmt.Fprintf(&contents, "target_sources(%s\n", cmakeName)
	fmt.Fprintln(&contents, "  PRIVATE")

	err = e.writeSrcsAndHdrs(rule, &contents, r)
	if err != nil {
		return skerr.Wrap(err)
	}
	fmt.Fprintln(&contents, ")")
	err = e.writeProperties(r, qr, &contents)
	if err != nil {
		return skerr.Wrap(err)
	}

	rule.setContents(contents.Bytes())

	return nil
}

// Export will convert the input Bazel cquery output, provided by the
// supplied QueryCommand parameter, to CMake. The equivalent
// CMake project definition will be written using the supplied writer.
func (e *CMakeExporter) Export(qcmd interfaces.QueryCommand, writer interfaces.Writer, projName string) error {

	in, err := qcmd.Read()
	if err != nil {
		return skerr.Wrapf(err, "error reading Bazel cquery data")
	}
	qr := analysis_v2.CqueryResult{}
	if err := proto.Unmarshal(in, &qr); err != nil {
		return skerr.Wrapf(err, "failed to unmarshal Bazel cquery result")
	}

	fmt.Fprintln(writer, "# DO NOT EDIT: This file is auto-generated.")
	fmt.Fprintln(writer, "cmake_minimum_required(VERSION 3.13)")
	writer.WriteString("\n")
	fmt.Fprintf(writer, "project(%s LANGUAGES C CXX)\n", projName)
	writer.WriteString("\n")

	writePlatformCompileFlags(writer)
	writer.WriteString("\n")

	for _, result := range qr.GetResults() {
		t := result.GetTarget()
		r := t.GetRule()
		if isExternalRule(r.GetName()) {
			continue
		}
		var err error = nil
		switch {
		case r.GetRuleClass() == "cc_binary":
			err = e.convertCCBinaryRule(r, &qr)
		case r.GetRuleClass() == "cc_library":
			err = e.convertCCLibraryRule(r, &qr)
		case r.GetRuleClass() == "filegroup":
			err = e.convertFilegroupRule(r)
		}
		if err != nil {
			return skerr.Wrapf(err, "failed to convert %s", r.GetRuleClass())
		}
	}

	_, err = e.workspace.write(writer)
	if err != nil {
		return skerr.Wrap(err)
	}

	return nil
}

// Make sure CMakeExporter fulfills the Exporter interface.
var _ interfaces.Exporter = (*CMakeExporter)(nil)
