// Copyright 2019 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 diff

import (
	"fmt"
	"strings"

	"golang.org/x/tools/internal/span"
)

// Unified represents a set of edits as a unified diff.
type Unified struct {
	// From is the name of the original file.
	From string
	// To is the name of the modified file.
	To string
	// Hunks is the set of edit hunks needed to transform the file content.
	Hunks []*Hunk
}

// Hunk represents a contiguous set of line edits to apply.
type Hunk struct {
	// The line in the original source where the hunk starts.
	FromLine int
	// The line in the original source where the hunk finishes.
	ToLine int
	// The set of line based edits to apply.
	Lines []Line
}

// Line represents a single line operation to apply as part of a Hunk.
type Line struct {
	// Kind is the type of line this represents, deletion, insertion or copy.
	Kind OpKind
	// Content is the content of this line.
	// For deletion it is the line being removed, for all others it is the line
	// to put in the output.
	Content string
}

// OpKind is used to denote the type of operation a line represents.
type OpKind int

const (
	// Delete is the operation kind for a line that is present in the input
	// but not in the output.
	Delete OpKind = iota
	// Insert is the operation kind for a line that is new in the output.
	Insert
	// Equal is the operation kind for a line that is the same in the input and
	// output, often used to provide context around edited lines.
	Equal
)

// String returns a human readable representation of an OpKind. It is not
// intended for machine processing.
func (k OpKind) String() string {
	switch k {
	case Delete:
		return "delete"
	case Insert:
		return "insert"
	case Equal:
		return "equal"
	default:
		panic("unknown operation kind")
	}
}

const (
	edge = 3
	gap  = edge * 2
)

// ToUnified takes a file contents and a sequence of edits, and calculates
// a unified diff that represents those edits.
func ToUnified(from, to string, content string, edits []TextEdit) Unified {
	u := Unified{
		From: from,
		To:   to,
	}
	if len(edits) == 0 {
		return u
	}
	lines := splitLines(content)
	var h *Hunk
	last := 0
	c := span.NewContentConverter(from, []byte(content))
	toLine := 0
	for _, edit := range edits {
		spn, _ := edit.Span.WithAll(c)
		start := spn.Start().Line() - 1
		end := spn.End().Line() - 1
		if spn.Start().Column() > 1 || spn.End().Column() > 1 {
			panic("cannot convert partial line edits to unified diff")
		}
		switch {
		case start < last:
			panic("cannot convert unsorted edits to unified diff")
		case h != nil && start == last:
			//direct extension
		case h != nil && start <= last+gap:
			//within range of previous lines, add the joiners
			addEqualLines(h, lines, last, start)
		default:
			//need to start a new hunk
			if h != nil {
				// add the edge to the previous hunk
				addEqualLines(h, lines, last, last+edge)
				u.Hunks = append(u.Hunks, h)
			}
			toLine += start - last
			h = &Hunk{
				FromLine: start + 1,
				ToLine:   toLine + 1,
			}
			// add the edge to the new hunk
			delta := addEqualLines(h, lines, start-edge, start)
			h.FromLine -= delta
			h.ToLine -= delta
		}
		last = start
		if edit.NewText == "" {
			for i := start; i < end; i++ {
				h.Lines = append(h.Lines, Line{Kind: Delete, Content: lines[i]})
				last++
			}
		} else {
			for _, line := range splitLines(edit.NewText) {
				h.Lines = append(h.Lines, Line{Kind: Insert, Content: line})
				toLine++
			}
		}
	}
	if h != nil {
		// add the edge to the final hunk
		addEqualLines(h, lines, last, last+edge)
		u.Hunks = append(u.Hunks, h)
	}
	return u
}

func splitLines(text string) []string {
	lines := strings.SplitAfter(text, "\n")
	if lines[len(lines)-1] == "" {
		lines = lines[:len(lines)-1]
	}
	return lines
}

func addEqualLines(h *Hunk, lines []string, start, end int) int {
	delta := 0
	for i := start; i < end; i++ {
		if i < 0 {
			continue
		}
		if i >= len(lines) {
			return delta
		}
		h.Lines = append(h.Lines, Line{Kind: Equal, Content: lines[i]})
		delta++
	}
	return delta
}

// Format converts a unified diff to the standard textual form for that diff.
// The output of this function can be passed to tools like patch.
func (u Unified) Format(f fmt.State, r rune) {
	if len(u.Hunks) == 0 {
		return
	}
	fmt.Fprintf(f, "--- %s\n", u.From)
	fmt.Fprintf(f, "+++ %s\n", u.To)
	for _, hunk := range u.Hunks {
		fromCount, toCount := 0, 0
		for _, l := range hunk.Lines {
			switch l.Kind {
			case Delete:
				fromCount++
			case Insert:
				toCount++
			default:
				fromCount++
				toCount++
			}
		}
		fmt.Fprint(f, "@@")
		if fromCount > 1 {
			fmt.Fprintf(f, " -%d,%d", hunk.FromLine, fromCount)
		} else {
			fmt.Fprintf(f, " -%d", hunk.FromLine)
		}
		if toCount > 1 {
			fmt.Fprintf(f, " +%d,%d", hunk.ToLine, toCount)
		} else {
			fmt.Fprintf(f, " +%d", hunk.ToLine)
		}
		fmt.Fprint(f, " @@\n")
		for _, l := range hunk.Lines {
			switch l.Kind {
			case Delete:
				fmt.Fprintf(f, "-%s", l.Content)
			case Insert:
				fmt.Fprintf(f, "+%s", l.Content)
			default:
				fmt.Fprintf(f, " %s", l.Content)
			}
			if !strings.HasSuffix(l.Content, "\n") {
				fmt.Fprintf(f, "\n\\ No newline at end of file\n")
			}
		}
	}
}
