// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package printer

import (
	"go/build/constraint"
	"sort"
	"text/tabwriter"
)

func (p *printer) fixGoBuildLines() {
	if len(p.goBuild)+len(p.plusBuild) == 0 {
		return
	}

	// Find latest possible placement of //go:build and // +build comments.
	// That's just after the last blank line before we find a non-comment.
	// (We'll add another blank line after our comment block.)
	// When we start dropping // +build comments, we can skip over /* */ comments too.
	// Note that we are processing tabwriter input, so every comment
	// begins and ends with a tabwriter.Escape byte.
	// And some newlines have turned into \f bytes.
	insert := 0
	for pos := 0; ; {
		// Skip leading space at beginning of line.
		blank := true
		for pos < len(p.output) && (p.output[pos] == ' ' || p.output[pos] == '\t') {
			pos++
		}
		// Skip over // comment if any.
		if pos+3 < len(p.output) && p.output[pos] == tabwriter.Escape && p.output[pos+1] == '/' && p.output[pos+2] == '/' {
			blank = false
			for pos < len(p.output) && !isNL(p.output[pos]) {
				pos++
			}
		}
		// Skip over \n at end of line.
		if pos >= len(p.output) || !isNL(p.output[pos]) {
			break
		}
		pos++

		if blank {
			insert = pos
		}
	}

	// If there is a //go:build comment before the place we identified,
	// use that point instead. (Earlier in the file is always fine.)
	if len(p.goBuild) > 0 && p.goBuild[0] < insert {
		insert = p.goBuild[0]
	} else if len(p.plusBuild) > 0 && p.plusBuild[0] < insert {
		insert = p.plusBuild[0]
	}

	var x constraint.Expr
	switch len(p.goBuild) {
	case 0:
		// Synthesize //go:build expression from // +build lines.
		for _, pos := range p.plusBuild {
			y, err := constraint.Parse(p.commentTextAt(pos))
			if err != nil {
				x = nil
				break
			}
			if x == nil {
				x = y
			} else {
				x = &constraint.AndExpr{X: x, Y: y}
			}
		}
	case 1:
		// Parse //go:build expression.
		x, _ = constraint.Parse(p.commentTextAt(p.goBuild[0]))
	}

	var block []byte
	if x == nil {
		// Don't have a valid //go:build expression to treat as truth.
		// Bring all the lines together but leave them alone.
		// Note that these are already tabwriter-escaped.
		for _, pos := range p.goBuild {
			block = append(block, p.lineAt(pos)...)
		}
		for _, pos := range p.plusBuild {
			block = append(block, p.lineAt(pos)...)
		}
	} else {
		block = append(block, tabwriter.Escape)
		block = append(block, "//go:build "...)
		block = append(block, x.String()...)
		block = append(block, tabwriter.Escape, '\n')
		if len(p.plusBuild) > 0 {
			lines, err := constraint.PlusBuildLines(x)
			if err != nil {
				lines = []string{"// +build error: " + err.Error()}
			}
			for _, line := range lines {
				block = append(block, tabwriter.Escape)
				block = append(block, line...)
				block = append(block, tabwriter.Escape, '\n')
			}
		}
	}
	block = append(block, '\n')

	// Build sorted list of lines to delete from remainder of output.
	toDelete := append(p.goBuild, p.plusBuild...)
	sort.Ints(toDelete)

	// Collect output after insertion point, with lines deleted, into after.
	var after []byte
	start := insert
	for _, end := range toDelete {
		if end < start {
			continue
		}
		after = appendLines(after, p.output[start:end])
		start = end + len(p.lineAt(end))
	}
	after = appendLines(after, p.output[start:])
	if n := len(after); n >= 2 && isNL(after[n-1]) && isNL(after[n-2]) {
		after = after[:n-1]
	}

	p.output = p.output[:insert]
	p.output = append(p.output, block...)
	p.output = append(p.output, after...)
}

// appendLines is like append(x, y...)
// but it avoids creating doubled blank lines,
// which would not be gofmt-standard output.
// It assumes that only whole blocks of lines are being appended,
// not line fragments.
func appendLines(x, y []byte) []byte {
	if len(y) > 0 && isNL(y[0]) && // y starts in blank line
		(len(x) == 0 || len(x) >= 2 && isNL(x[len(x)-1]) && isNL(x[len(x)-2])) { // x is empty or ends in blank line
		y = y[1:] // delete y's leading blank line
	}
	return append(x, y...)
}

func (p *printer) lineAt(start int) []byte {
	pos := start
	for pos < len(p.output) && !isNL(p.output[pos]) {
		pos++
	}
	if pos < len(p.output) {
		pos++
	}
	return p.output[start:pos]
}

func (p *printer) commentTextAt(start int) string {
	if start < len(p.output) && p.output[start] == tabwriter.Escape {
		start++
	}
	pos := start
	for pos < len(p.output) && p.output[pos] != tabwriter.Escape && !isNL(p.output[pos]) {
		pos++
	}
	return string(p.output[start:pos])
}

func isNL(b byte) bool {
	return b == '\n' || b == '\f'
}
