// 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,
	}
}

// Determine if a target refers to a file, or a rule. target is of
// the form:
//
// file: //include/private:SingleOwner.h
// rule: //bazel/common_config_settings:has_gpu_backend
func isFileTarget(target string) bool {
	_, _, target, err := parseRule(target)
	if err != nil {
		return false
	}
	return strings.Contains(target, ".")
}

// Given a Bazel rule name find that rule from within the
// query results.
func findRule(qr *analysis_v2.CqueryResult, name string) (*build.Rule, error) {
	for _, result := range qr.GetResults() {
		r := result.GetTarget().GetRule()
		if r.GetName() == name {
			return r, nil
		}
	}
	return nil, skerr.Fmt(`cannot find rule %q`, name)
}

// 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())
	for idx, inc := range includes {
		if inc == "." {
			includes[idx] = ruleDir
		}
	}
	for _, d := range deps {
		dr, err := findRule(qr, d)
		if err != nil {
			return nil, skerr.Wrap(err)
		}
		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, err := findRule(qr, d)
		if err != nil {
			return nil, skerr.Wrap(err)
		}
		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 := getRuleCMakeName(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 := getRuleCMakeName(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 := getRuleCMakeName(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 := getRuleCMakeName(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 := getRuleCMakeName(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 := getRuleCMakeName(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 := getRuleCMakeName(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 := getRuleCMakeName(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()
		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)
