// 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, lit, 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
}
