// 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
	maxIndentDepth = 2
	lineWidth      = 80
)

var indentString = strings.Repeat(" ", indentWidth*maxIndentDepth)

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(comment string, rule string, outputs, implicitOuts,
	explicitDeps, implicitDeps, orderOnlyDeps []string) error {

	n.justDidBlankLine = false

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

	wrapper := ninjaWriterWithWrap{
		ninjaWriter: n,
		maxLineLen:  maxLineLen,
	}

	if comment != "" {
		wrapper.Comment(comment)
	}

	wrapper.WriteString("build")

	for _, output := range outputs {
		wrapper.WriteStringWithSpace(output)
	}

	if len(implicitOuts) > 0 {
		wrapper.WriteStringWithSpace("|")

		for _, out := range implicitOuts {
			wrapper.WriteStringWithSpace(out)
		}
	}

	wrapper.WriteString(":")

	wrapper.WriteStringWithSpace(rule)

	for _, dep := range explicitDeps {
		wrapper.WriteStringWithSpace(dep)
	}

	if len(implicitDeps) > 0 {
		wrapper.WriteStringWithSpace("|")

		for _, dep := range implicitDeps {
			wrapper.WriteStringWithSpace(dep)
		}
	}

	if len(orderOnlyDeps) > 0 {
		wrapper.WriteStringWithSpace("||")

		for _, dep := range orderOnlyDeps {
			wrapper.WriteStringWithSpace(dep)
		}
	}

	return wrapper.Flush()
}

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
	_, err := fmt.Fprintf(n.writer, "%s%s = %s\n", indentString[:indentWidth], name, value)
	return err
}

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

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

	wrapper := ninjaWriterWithWrap{
		ninjaWriter: n,
		maxLineLen:  maxLineLen,
	}

	wrapper.WriteString("default")

	for _, target := range targets {
		wrapper.WriteString(" " + target)
	}

	return wrapper.Flush()
}

func (n *ninjaWriter) Subninja(file string) error {
	n.justDidBlankLine = false
	_, err := fmt.Fprintf(n.writer, "subninja %s\n", file)
	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
}

type ninjaWriterWithWrap struct {
	*ninjaWriter
	maxLineLen int
	writtenLen int
	err        error
}

func (n *ninjaWriterWithWrap) writeString(s string, space bool) {
	if n.err != nil {
		return
	}

	spaceLen := 0
	if space {
		spaceLen = 1
	}

	if n.writtenLen+len(s)+spaceLen > n.maxLineLen {
		_, n.err = io.WriteString(n.writer, " $\n")
		if n.err != nil {
			return
		}
		_, n.err = io.WriteString(n.writer, indentString[:indentWidth*2])
		if n.err != nil {
			return
		}
		n.writtenLen = indentWidth * 2
		s = strings.TrimLeftFunc(s, unicode.IsSpace)
	} else if space {
		io.WriteString(n.writer, " ")
		n.writtenLen++
	}

	_, n.err = io.WriteString(n.writer, s)
	n.writtenLen += len(s)
}

func (n *ninjaWriterWithWrap) WriteString(s string) {
	n.writeString(s, false)
}

func (n *ninjaWriterWithWrap) WriteStringWithSpace(s string) {
	n.writeString(s, true)
}

func (n *ninjaWriterWithWrap) Flush() error {
	if n.err != nil {
		return n.err
	}
	_, err := io.WriteString(n.writer, "\n")
	return err
}
