// Copyright 2014 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package blueprint

import (
	"fmt"
	"io"
	"strings"
	"unicode"
)

const (
	indentWidth = 4
	lineWidth   = 80
)

type ninjaWriter struct {
	writer io.Writer

	justDidBlankLine bool // true if the last operation was a BlankLine
}

func newNinjaWriter(writer io.Writer) *ninjaWriter {
	return &ninjaWriter{
		writer: writer,
	}
}

func (n *ninjaWriter) Comment(comment string) error {
	n.justDidBlankLine = false

	const lineHeaderLen = len("# ")
	const maxLineLen = lineWidth - lineHeaderLen

	var lineStart, lastSplitPoint int
	for i, r := range comment {
		if unicode.IsSpace(r) {
			// We know we can safely split the line here.
			lastSplitPoint = i + 1
		}

		var line string
		var writeLine bool
		switch {
		case r == '\n':
			// Output the line without trimming the left so as to allow comments
			// to contain their own indentation.
			line = strings.TrimRightFunc(comment[lineStart:i], unicode.IsSpace)
			writeLine = true

		case (i-lineStart > maxLineLen) && (lastSplitPoint > lineStart):
			// The line has grown too long and is splittable.  Split it at the
			// last split point.
			line = strings.TrimSpace(comment[lineStart:lastSplitPoint])
			writeLine = true
		}

		if writeLine {
			line = strings.TrimSpace("# "+line) + "\n"
			_, err := io.WriteString(n.writer, line)
			if err != nil {
				return err
			}
			lineStart = lastSplitPoint
		}
	}

	if lineStart != len(comment) {
		line := strings.TrimSpace(comment[lineStart:])
		_, err := fmt.Fprintf(n.writer, "# %s\n", line)
		if err != nil {
			return err
		}
	}

	return nil
}

func (n *ninjaWriter) Pool(name string) error {
	n.justDidBlankLine = false
	_, err := fmt.Fprintf(n.writer, "pool %s\n", name)
	return err
}

func (n *ninjaWriter) Rule(name string) error {
	n.justDidBlankLine = false
	_, err := fmt.Fprintf(n.writer, "rule %s\n", name)
	return err
}

func (n *ninjaWriter) Build(rule string, outputs, explicitDeps, implicitDeps,
	orderOnlyDeps []string) error {

	n.justDidBlankLine = false

	const lineWrapLen = len(" $")
	const maxLineLen = lineWidth - lineWrapLen

	line := "build"

	appendWithWrap := func(s string) (err error) {
		if len(line)+len(s) > maxLineLen {
			_, err = fmt.Fprintf(n.writer, "%s $\n", line)
			line = strings.Repeat(" ", indentWidth*2)
			s = strings.TrimLeftFunc(s, unicode.IsSpace)
		}
		line += s
		return
	}

	for _, output := range outputs {
		err := appendWithWrap(" " + output)
		if err != nil {
			return err
		}
	}

	err := appendWithWrap(":")
	if err != nil {
		return err
	}

	err = appendWithWrap(" " + rule)
	if err != nil {
		return err
	}

	for _, dep := range explicitDeps {
		err := appendWithWrap(" " + dep)
		if err != nil {
			return err
		}
	}

	if len(implicitDeps) > 0 {
		err := appendWithWrap(" |")
		if err != nil {
			return err
		}

		for _, dep := range implicitDeps {
			err := appendWithWrap(" " + dep)
			if err != nil {
				return err
			}
		}
	}

	if len(orderOnlyDeps) > 0 {
		err := appendWithWrap(" ||")
		if err != nil {
			return err
		}

		for _, dep := range orderOnlyDeps {
			err := appendWithWrap(" " + dep)
			if err != nil {
				return err
			}
		}
	}

	_, err = fmt.Fprintln(n.writer, line)
	return err
}

func (n *ninjaWriter) Assign(name, value string) error {
	n.justDidBlankLine = false
	_, err := fmt.Fprintf(n.writer, "%s = %s\n", name, value)
	return err
}

func (n *ninjaWriter) ScopedAssign(name, value string) error {
	n.justDidBlankLine = false
	indent := strings.Repeat(" ", indentWidth)
	_, err := fmt.Fprintf(n.writer, "%s%s = %s\n", indent, name, value)
	return err
}

func (n *ninjaWriter) Default(targets ...string) error {
	n.justDidBlankLine = false

	const lineWrapLen = len(" $")
	const maxLineLen = lineWidth - lineWrapLen

	line := "default"

	appendWithWrap := func(s string) (err error) {
		if len(line)+len(s) > maxLineLen {
			_, err = fmt.Fprintf(n.writer, "%s $\n", line)
			line = strings.Repeat(" ", indentWidth*2)
			s = strings.TrimLeftFunc(s, unicode.IsSpace)
		}
		line += s
		return
	}

	for _, target := range targets {
		err := appendWithWrap(" " + target)
		if err != nil {
			return err
		}
	}

	_, err := fmt.Fprintln(n.writer, line)
	return err
}

func (n *ninjaWriter) BlankLine() (err error) {
	// We don't output multiple blank lines in a row.
	if !n.justDidBlankLine {
		n.justDidBlankLine = true
		_, err = io.WriteString(n.writer, "\n")
	}
	return err
}

func writeAssignments(w io.Writer, indent int, assignments ...string) error {
	var maxNameLen int
	for i := 0; i < len(assignments); i += 2 {
		name := assignments[i]
		err := validateNinjaName(name)
		if err != nil {
			return err
		}
		if maxNameLen < len(name) {
			maxNameLen = len(name)
		}
	}

	indentStr := strings.Repeat(" ", indent*indentWidth)
	extraIndentStr := strings.Repeat(" ", (indent+1)*indentWidth)
	replacer := strings.NewReplacer("\n", "$\n"+extraIndentStr)

	for i := 0; i < len(assignments); i += 2 {
		name := assignments[i]
		value := replacer.Replace(assignments[i+1])
		_, err := fmt.Fprintf(w, "%s% *s = %s\n", indentStr, maxNameLen, name,
			value)
		if err != nil {
			return err
		}
	}

	return nil
}
