// 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 (
	"fmt"
	"io"

	"go.skia.org/infra/go/skerr"
	"go.skia.org/infra/go/util"
	"go.skia.org/skia/bazel/exporter/build_proto/build"
)

// cmakeWorkspace represents the entire state of a CMake project.
type cmakeWorkspace struct {
	// Map Bazel rule names to cmakeRule instances. Holding pointer
	// values as the rules are mutable.
	rules map[string]*cmakeRule
}

// writeState tracks the state of an in-progress write of the workspace.
type writeState struct {
	writtenRules []string // All cmakeRule's written during write.
}

// newCMakeWorkspace will create a new CMake workspace object.
func newCMakeWorkspace() *cmakeWorkspace {
	return &cmakeWorkspace{rules: map[string]*cmakeRule{}}
}

// Determine if a rule has been written.
func (s *writeState) isRuleWritten(ruleName string) bool {
	return util.In(ruleName, s.writtenRules)
}

// setRuleWritten will mark the rule as having been written.
func (s *writeState) setRuleWritten(ruleName string) {
	s.writtenRules = append(s.writtenRules, ruleName)
}

// getRule will return the CMake wrapper for a Bazel rule given the
// rule name. Will return nil if there is no corresponding rule.
func (w *cmakeWorkspace) getRule(name string) *cmakeRule {
	return w.rules[name]
}

// createRule will create (if necessary) a new CMake rule object
// for the given rule name.
func (w *cmakeWorkspace) createRule(rule *build.Rule) *cmakeRule {
	if r := w.getRule(rule.GetName()); r != nil {
		return r
	}
	r := newCMakeRule(rule)
	w.rules[rule.GetName()] = r
	return r
}

// writeRule will write the given rule to the writer.
// It will first write all dependent rules so that they appear
// in the CMake project file before the rule that depends on them.
func (w *cmakeWorkspace) writeRule(writer io.Writer, r *cmakeRule, state *writeState) (int, error) {
	nb := 0
	if !r.hasSrcs() {
		return 0, nil
	}
	// First write all dependencies because CMake does not support forward references.
	for _, name := range r.deps {
		dep := w.getRule(name)
		if dep == nil {
			return 0, skerr.Fmt(`cannot find rule %q`, name)
		}
		n, err := w.writeRule(writer, dep, state)
		if err != nil {
			return nb, skerr.Wrap(err)
		}
		nb += n
	}
	if state.isRuleWritten(r.getName()) {
		return nb, nil
	}
	num, err := fmt.Fprintln(writer)
	if err != nil {
		return nb, skerr.Wrap(err)
	}
	nb += num
	num, err = r.write(writer)
	if err != nil {
		return nb, skerr.Wrap(err)
	}
	state.setRuleWritten(r.getName())
	nb += num
	return nb, nil
}

// Write this workspace using the given writer.
func (w *cmakeWorkspace) write(writer io.Writer) (int, error) {
	var state writeState
	nb := 0
	for _, r := range w.rules {
		num, err := w.writeRule(writer, r, &state)
		if err != nil {
			return nb, skerr.Wrap(err)
		}
		nb += num
	}
	return nb, nil
}
