// Package revision extracts git revision from string
// More informations about revision : https://www.kernel.org/pub/software/scm/git/docs/gitrevisions.html
package revision

import (
	"bytes"
	"fmt"
	"io"
	"regexp"
	"strconv"
	"time"
)

// ErrInvalidRevision is emitted if string doesn't match valid revision
type ErrInvalidRevision struct {
	s string
}

func (e *ErrInvalidRevision) Error() string {
	return "Revision invalid : " + e.s
}

// Revisioner represents a revision component.
// A revision is made of multiple revision components
// obtained after parsing a revision string,
// for instance revision "master~" will be converted in
// two revision components Ref and TildePath
type Revisioner interface {
}

// Ref represents a reference name : HEAD, master
type Ref string

// TildePath represents ~, ~{n}
type TildePath struct {
	Depth int
}

// CaretPath represents ^, ^{n}
type CaretPath struct {
	Depth int
}

// CaretReg represents ^{/foo bar}
type CaretReg struct {
	Regexp *regexp.Regexp
	Negate bool
}

// CaretType represents ^{commit}
type CaretType struct {
	ObjectType string
}

// AtReflog represents @{n}
type AtReflog struct {
	Depth int
}

// AtCheckout represents @{-n}
type AtCheckout struct {
	Depth int
}

// AtUpstream represents @{upstream}, @{u}
type AtUpstream struct {
	BranchName string
}

// AtPush represents @{push}
type AtPush struct {
	BranchName string
}

// AtDate represents @{"2006-01-02T15:04:05Z"}
type AtDate struct {
	Date time.Time
}

// ColonReg represents :/foo bar
type ColonReg struct {
	Regexp *regexp.Regexp
	Negate bool
}

// ColonPath represents :./<path> :<path>
type ColonPath struct {
	Path string
}

// ColonStagePath represents :<n>:/<path>
type ColonStagePath struct {
	Path  string
	Stage int
}

// Parser represents a parser
// use to tokenize and transform to revisioner chunks
// a given string
type Parser struct {
	s                 *scanner
	currentParsedChar struct {
		tok token
		lit string
	}
	unreadLastChar bool
}

// NewParserFromString returns a new instance of parser from a string.
func NewParserFromString(s string) *Parser {
	return NewParser(bytes.NewBufferString(s))
}

// NewParser returns a new instance of parser.
func NewParser(r io.Reader) *Parser {
	return &Parser{s: newScanner(r)}
}

// scan returns the next token from the underlying scanner
// or the last scanned token if an unscan was requested
func (p *Parser) scan() (token, string, error) {
	if p.unreadLastChar {
		p.unreadLastChar = false
		return p.currentParsedChar.tok, p.currentParsedChar.lit, nil
	}

	tok, lit, err := p.s.scan()

	p.currentParsedChar.tok, p.currentParsedChar.lit = tok, lit

	return tok, lit, err
}

// unscan pushes the previously read token back onto the buffer.
func (p *Parser) unscan() { p.unreadLastChar = true }

// Parse explode a revision string into revisioner chunks
func (p *Parser) Parse() ([]Revisioner, error) {
	var rev Revisioner
	var revs []Revisioner
	var tok token
	var err error

	for {
		tok, _, err = p.scan()

		if err != nil {
			return nil, err
		}

		switch tok {
		case at:
			rev, err = p.parseAt()
		case tilde:
			rev, err = p.parseTilde()
		case caret:
			rev, err = p.parseCaret()
		case colon:
			rev, err = p.parseColon()
		case eof:
			err = p.validateFullRevision(&revs)

			if err != nil {
				return []Revisioner{}, err
			}

			return revs, nil
		default:
			p.unscan()
			rev, err = p.parseRef()
		}

		if err != nil {
			return []Revisioner{}, err
		}

		revs = append(revs, rev)
	}
}

// validateFullRevision ensures all revisioner chunks make a valid revision
func (p *Parser) validateFullRevision(chunks *[]Revisioner) error {
	var hasReference bool

	for i, chunk := range *chunks {
		switch chunk.(type) {
		case Ref:
			if i == 0 {
				hasReference = true
			} else {
				return &ErrInvalidRevision{`reference must be defined once at the beginning`}
			}
		case AtDate:
			if len(*chunks) == 1 || hasReference && len(*chunks) == 2 {
				return nil
			}

			return &ErrInvalidRevision{`"@" statement is not valid, could be : <refname>@{<ISO-8601 date>}, @{<ISO-8601 date>}`}
		case AtReflog:
			if len(*chunks) == 1 || hasReference && len(*chunks) == 2 {
				return nil
			}

			return &ErrInvalidRevision{`"@" statement is not valid, could be : <refname>@{<n>}, @{<n>}`}
		case AtCheckout:
			if len(*chunks) == 1 {
				return nil
			}

			return &ErrInvalidRevision{`"@" statement is not valid, could be : @{-<n>}`}
		case AtUpstream:
			if len(*chunks) == 1 || hasReference && len(*chunks) == 2 {
				return nil
			}

			return &ErrInvalidRevision{`"@" statement is not valid, could be : <refname>@{upstream}, @{upstream}, <refname>@{u}, @{u}`}
		case AtPush:
			if len(*chunks) == 1 || hasReference && len(*chunks) == 2 {
				return nil
			}

			return &ErrInvalidRevision{`"@" statement is not valid, could be : <refname>@{push}, @{push}`}
		case TildePath, CaretPath, CaretReg:
			if !hasReference {
				return &ErrInvalidRevision{`"~" or "^" statement must have a reference defined at the beginning`}
			}
		case ColonReg:
			if len(*chunks) == 1 {
				return nil
			}

			return &ErrInvalidRevision{`":" statement is not valid, could be : :/<regexp>`}
		case ColonPath:
			if i == len(*chunks)-1 && hasReference || len(*chunks) == 1 {
				return nil
			}

			return &ErrInvalidRevision{`":" statement is not valid, could be : <revision>:<path>`}
		case ColonStagePath:
			if len(*chunks) == 1 {
				return nil
			}

			return &ErrInvalidRevision{`":" statement is not valid, could be : :<n>:<path>`}
		}
	}

	return nil
}

// parseAt extract @ statements
func (p *Parser) parseAt() (Revisioner, error) {
	var tok, nextTok token
	var lit, nextLit string
	var err error

	tok, _, err = p.scan()

	if err != nil {
		return nil, err
	}

	if tok != obrace {
		p.unscan()

		return Ref("HEAD"), nil
	}

	tok, lit, err = p.scan()

	if err != nil {
		return nil, err
	}

	nextTok, nextLit, err = p.scan()

	if err != nil {
		return nil, err
	}

	switch {
	case tok == word && (lit == "u" || lit == "upstream") && nextTok == cbrace:
		return AtUpstream{}, nil
	case tok == word && lit == "push" && nextTok == cbrace:
		return AtPush{}, nil
	case tok == number && nextTok == cbrace:
		n, _ := strconv.Atoi(lit)

		return AtReflog{n}, nil
	case tok == minus && nextTok == number:
		n, _ := strconv.Atoi(nextLit)

		t, _, err := p.scan()

		if err != nil {
			return nil, err
		}

		if t != cbrace {
			return nil, &ErrInvalidRevision{fmt.Sprintf(`missing "}" in @{-n} structure`)}
		}

		return AtCheckout{n}, nil
	default:
		p.unscan()

		date := lit

		for {
			tok, lit, err = p.scan()

			if err != nil {
				return nil, err
			}

			switch {
			case tok == cbrace:
				t, err := time.Parse("2006-01-02T15:04:05Z", date)

				if err != nil {
					return nil, &ErrInvalidRevision{fmt.Sprintf(`wrong date "%s" must fit ISO-8601 format : 2006-01-02T15:04:05Z`, date)}
				}

				return AtDate{t}, nil
			default:
				date += lit
			}
		}
	}
}

// parseTilde extract ~ statements
func (p *Parser) parseTilde() (Revisioner, error) {
	var tok token
	var lit string
	var err error

	tok, lit, err = p.scan()

	if err != nil {
		return nil, err
	}

	switch {
	case tok == number:
		n, _ := strconv.Atoi(lit)

		return TildePath{n}, nil
	default:
		p.unscan()
		return TildePath{1}, nil
	}
}

// parseCaret extract ^ statements
func (p *Parser) parseCaret() (Revisioner, error) {
	var tok token
	var lit string
	var err error

	tok, lit, err = p.scan()

	if err != nil {
		return nil, err
	}

	switch {
	case tok == obrace:
		r, err := p.parseCaretBraces()

		if err != nil {
			return nil, err
		}

		return r, nil
	case tok == number:
		n, _ := strconv.Atoi(lit)

		if n > 2 {
			return nil, &ErrInvalidRevision{fmt.Sprintf(`"%s" found must be 0, 1 or 2 after "^"`, lit)}
		}

		return CaretPath{n}, nil
	default:
		p.unscan()
		return CaretPath{1}, nil
	}
}

// parseCaretBraces extract ^{<data>} statements
func (p *Parser) parseCaretBraces() (Revisioner, error) {
	var tok, nextTok token
	var lit, _ string
	start := true
	var re string
	var negate bool
	var err error

	for {
		tok, lit, err = p.scan()

		if err != nil {
			return nil, err
		}

		nextTok, _, err = p.scan()

		if err != nil {
			return nil, err
		}

		switch {
		case tok == word && nextTok == cbrace && (lit == "commit" || lit == "tree" || lit == "blob" || lit == "tag" || lit == "object"):
			return CaretType{lit}, nil
		case re == "" && tok == cbrace:
			return CaretType{"tag"}, nil
		case re == "" && tok == emark && nextTok == emark:
			re += lit
		case re == "" && tok == emark && nextTok == minus:
			negate = true
		case re == "" && tok == emark:
			return nil, &ErrInvalidRevision{fmt.Sprintf(`revision suffix brace component sequences starting with "/!" others than those defined are reserved`)}
		case re == "" && tok == slash:
			p.unscan()
		case tok != slash && start:
			return nil, &ErrInvalidRevision{fmt.Sprintf(`"%s" is not a valid revision suffix brace component`, lit)}
		case tok != cbrace:
			p.unscan()
			re += lit
		case tok == cbrace:
			p.unscan()

			reg, err := regexp.Compile(re)

			if err != nil {
				return CaretReg{}, &ErrInvalidRevision{fmt.Sprintf(`revision suffix brace component, %s`, err.Error())}
			}

			return CaretReg{reg, negate}, nil
		}

		start = false
	}
}

// parseColon extract : statements
func (p *Parser) parseColon() (Revisioner, error) {
	var tok token
	var err error

	tok, _, err = p.scan()

	if err != nil {
		return nil, err
	}

	switch tok {
	case slash:
		return p.parseColonSlash()
	default:
		p.unscan()
		return p.parseColonDefault()
	}
}

// parseColonSlash extract :/<data> statements
func (p *Parser) parseColonSlash() (Revisioner, error) {
	var tok, nextTok token
	var lit string
	var re string
	var negate bool
	var err error

	for {
		tok, lit, err = p.scan()

		if err != nil {
			return nil, err
		}

		nextTok, _, err = p.scan()

		if err != nil {
			return nil, err
		}

		switch {
		case tok == emark && nextTok == emark:
			re += lit
		case re == "" && tok == emark && nextTok == minus:
			negate = true
		case re == "" && tok == emark:
			return nil, &ErrInvalidRevision{fmt.Sprintf(`revision suffix brace component sequences starting with "/!" others than those defined are reserved`)}
		case tok == eof:
			p.unscan()
			reg, err := regexp.Compile(re)

			if err != nil {
				return ColonReg{}, &ErrInvalidRevision{fmt.Sprintf(`revision suffix brace component, %s`, err.Error())}
			}

			return ColonReg{reg, negate}, nil
		default:
			p.unscan()
			re += lit
		}
	}
}

// parseColonDefault extract :<data> statements
func (p *Parser) parseColonDefault() (Revisioner, error) {
	var tok token
	var lit string
	var path string
	var stage int
	var err error
	var n = -1

	tok, lit, err = p.scan()

	if err != nil {
		return nil, err
	}

	nextTok, _, err := p.scan()

	if err != nil {
		return nil, err
	}

	if tok == number && nextTok == colon {
		n, _ = strconv.Atoi(lit)
	}

	switch n {
	case 0, 1, 2, 3:
		stage = n
	default:
		path += lit
		p.unscan()
	}

	for {
		tok, lit, err = p.scan()

		if err != nil {
			return nil, err
		}

		switch {
		case tok == eof && n == -1:
			return ColonPath{path}, nil
		case tok == eof:
			return ColonStagePath{path, stage}, nil
		default:
			path += lit
		}
	}
}

// parseRef extract reference name
func (p *Parser) parseRef() (Revisioner, error) {
	var tok, prevTok token
	var lit, buf string
	var endOfRef bool
	var err error

	for {
		tok, lit, err = p.scan()

		if err != nil {
			return nil, err
		}

		switch tok {
		case eof, at, colon, tilde, caret:
			endOfRef = true
		}

		err := p.checkRefFormat(tok, lit, prevTok, buf, endOfRef)

		if err != nil {
			return "", err
		}

		if endOfRef {
			p.unscan()
			return Ref(buf), nil
		}

		buf += lit
		prevTok = tok
	}
}

// checkRefFormat ensure reference name follow rules defined here :
// https://git-scm.com/docs/git-check-ref-format
func (p *Parser) checkRefFormat(token token, literal string, previousToken token, buffer string, endOfRef bool) error {
	switch token {
	case aslash, space, control, qmark, asterisk, obracket:
		return &ErrInvalidRevision{fmt.Sprintf(`must not contains "%s"`, literal)}
	}

	switch {
	case (token == dot || token == slash) && buffer == "":
		return &ErrInvalidRevision{fmt.Sprintf(`must not start with "%s"`, literal)}
	case previousToken == slash && endOfRef:
		return &ErrInvalidRevision{`must not end with "/"`}
	case previousToken == dot && endOfRef:
		return &ErrInvalidRevision{`must not end with "."`}
	case token == dot && previousToken == slash:
		return &ErrInvalidRevision{`must not contains "/."`}
	case previousToken == dot && token == dot:
		return &ErrInvalidRevision{`must not contains ".."`}
	case previousToken == slash && token == slash:
		return &ErrInvalidRevision{`must not contains consecutively "/"`}
	case (token == slash || endOfRef) && len(buffer) > 4 && buffer[len(buffer)-5:] == ".lock":
		return &ErrInvalidRevision{"cannot end with .lock"}
	}

	return nil
}
