// Copyright 2022 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 lcs

import (
	"log"
	"sort"
)

// lcs is a longest common sequence
type lcs []diag

// A diag is a piece of the edit graph where A[X+i] == B[Y+i], for 0<=i<Len.
// All computed diagonals are parts of a longest common subsequence.
type diag struct {
	X, Y int
	Len  int
}

// sort sorts in place, by lowest X, and if tied, inversely by Len
func (l lcs) sort() lcs {
	sort.Slice(l, func(i, j int) bool {
		if l[i].X != l[j].X {
			return l[i].X < l[j].X
		}
		return l[i].Len > l[j].Len
	})
	return l
}

// validate that the elements of the lcs do not overlap
// (can only happen when the two-sided algorithm ends early)
// expects the lcs to be sorted
func (l lcs) valid() bool {
	for i := 1; i < len(l); i++ {
		if l[i-1].X+l[i-1].Len > l[i].X {
			return false
		}
		if l[i-1].Y+l[i-1].Len > l[i].Y {
			return false
		}
	}
	return true
}

// repair overlapping lcs
// only called if two-sided stops early
func (l lcs) fix() lcs {
	// from the set of diagonals in l, find a maximal non-conflicting set
	// this problem may be NP-complete, but we use a greedy heuristic,
	// which is quadratic, but with a better data structure, could be D log D.
	// indepedent is not enough: {0,3,1} and {3,0,2} can't both occur in an lcs
	// which has to have monotone x and y
	if len(l) == 0 {
		return nil
	}
	sort.Slice(l, func(i, j int) bool { return l[i].Len > l[j].Len })
	tmp := make(lcs, 0, len(l))
	tmp = append(tmp, l[0])
	for i := 1; i < len(l); i++ {
		var dir direction
		nxt := l[i]
		for _, in := range tmp {
			if dir, nxt = overlap(in, nxt); dir == empty || dir == bad {
				break
			}
		}
		if nxt.Len > 0 && dir != bad {
			tmp = append(tmp, nxt)
		}
	}
	tmp.sort()
	if false && !tmp.valid() { // debug checking
		log.Fatalf("here %d", len(tmp))
	}
	return tmp
}

type direction int

const (
	empty    direction = iota // diag is empty (so not in lcs)
	leftdown                  // proposed acceptably to the left and below
	rightup                   // proposed diag is acceptably to the right and above
	bad                       // proposed diag is inconsistent with the lcs so far
)

// overlap trims the proposed diag prop  so it doesn't overlap with
// the existing diag that has already been added to the lcs.
func overlap(exist, prop diag) (direction, diag) {
	if prop.X <= exist.X && exist.X < prop.X+prop.Len {
		// remove the end of prop where it overlaps with the X end of exist
		delta := prop.X + prop.Len - exist.X
		prop.Len -= delta
		if prop.Len <= 0 {
			return empty, prop
		}
	}
	if exist.X <= prop.X && prop.X < exist.X+exist.Len {
		// remove the beginning of prop where overlaps with exist
		delta := exist.X + exist.Len - prop.X
		prop.Len -= delta
		if prop.Len <= 0 {
			return empty, prop
		}
		prop.X += delta
		prop.Y += delta
	}
	if prop.Y <= exist.Y && exist.Y < prop.Y+prop.Len {
		// remove the end of prop that overlaps (in Y) with exist
		delta := prop.Y + prop.Len - exist.Y
		prop.Len -= delta
		if prop.Len <= 0 {
			return empty, prop
		}
	}
	if exist.Y <= prop.Y && prop.Y < exist.Y+exist.Len {
		// remove the beginning of peop that overlaps with exist
		delta := exist.Y + exist.Len - prop.Y
		prop.Len -= delta
		if prop.Len <= 0 {
			return empty, prop
		}
		prop.X += delta // no test reaches this code
		prop.Y += delta
	}
	if prop.X+prop.Len <= exist.X && prop.Y+prop.Len <= exist.Y {
		return leftdown, prop
	}
	if exist.X+exist.Len <= prop.X && exist.Y+exist.Len <= prop.Y {
		return rightup, prop
	}
	// prop can't be in an lcs that contains exist
	return bad, prop
}

// manipulating Diag and lcs

// prepend a diagonal (x,y)-(x+1,y+1) segment either to an empty lcs
// or to its first Diag. prepend is only called to extend diagonals
// the backward direction.
func (lcs lcs) prepend(x, y int) lcs {
	if len(lcs) > 0 {
		d := &lcs[0]
		if int(d.X) == x+1 && int(d.Y) == y+1 {
			// extend the diagonal down and to the left
			d.X, d.Y = int(x), int(y)
			d.Len++
			return lcs
		}
	}

	r := diag{X: int(x), Y: int(y), Len: 1}
	lcs = append([]diag{r}, lcs...)
	return lcs
}

// append appends a diagonal, or extends the existing one.
// by adding the edge (x,y)-(x+1.y+1). append is only called
// to extend diagonals in the forward direction.
func (lcs lcs) append(x, y int) lcs {
	if len(lcs) > 0 {
		last := &lcs[len(lcs)-1]
		// Expand last element if adjoining.
		if last.X+last.Len == x && last.Y+last.Len == y {
			last.Len++
			return lcs
		}
	}

	return append(lcs, diag{X: x, Y: y, Len: 1})
}

// enforce constraint on d, k
func ok(d, k int) bool {
	return d >= 0 && -d <= k && k <= d
}
