// Copyright 2017 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 db

import (
	"fmt"
	"io"
	"strings"
	"unicode"
)

// operation is the enum for possible query operations.
type operation rune

// Query operations.
// Only equals, lt, and gt can be specified in a query.
// The order of these operations is used by merge.
const (
	equals operation = iota
	ltgt
	lt
	gt
)

// A part is a single query part with a key, operator, and value.
type part struct {
	key      string
	operator operation
	// value and value2 hold the values to compare against.
	value, value2 string
}

// sepToOperation maps runes to operation values.
var sepToOperation = map[byte]operation{
	':': equals,
	'<': lt,
	'>': gt,
}

// parseWord parse a single query part (as returned by SplitWords with quoting and escaping already removed) into a part struct.
func parseWord(word string) (part, error) {
	sepIndex := strings.IndexFunc(word, func(r rune) bool {
		return r == ':' || r == '>' || r == '<' || unicode.IsSpace(r) || unicode.IsUpper(r)
	})
	if sepIndex < 0 {
		return part{}, fmt.Errorf("query part %q is missing operator", word)
	}
	key, sep, value := word[:sepIndex], word[sepIndex], word[sepIndex+1:]
	if oper, ok := sepToOperation[sep]; ok {
		return part{key, oper, value, ""}, nil
	}
	return part{}, fmt.Errorf("query part %q has invalid key", word)
}

// merge merges two query parts together into a single query part.
// The keys of the two parts must be equal.
// If the result is a query part that can never match, io.EOF is returned as the error.
func (p part) merge(p2 part) (part, error) {
	if p2.operator < p.operator {
		// Sort the parts so we only need half the table below.
		p, p2 = p2, p
	}
	switch p.operator {
	case equals:
		switch p2.operator {
		case equals:
			if p.value == p2.value {
				return p, nil
			}
			return part{}, io.EOF
		case lt:
			if p.value < p2.value {
				return p, nil
			}
			return part{}, io.EOF
		case gt:
			if p.value > p2.value {
				return p, nil
			}
			return part{}, io.EOF
		case ltgt:
			if p.value < p2.value && p.value > p2.value2 {
				return p, nil
			}
			return part{}, io.EOF
		}
	case ltgt:
		switch p2.operator {
		case ltgt:
			if p2.value < p.value {
				p.value = p2.value
			}
			if p2.value2 > p.value2 {
				p.value2 = p2.value2
			}
		case lt:
			if p2.value < p.value {
				p.value = p2.value
			}
		case gt:
			if p2.value > p.value2 {
				p.value2 = p2.value
			}
		}
	case lt:
		switch p2.operator {
		case lt:
			if p2.value < p.value {
				return p2, nil
			}
			return p, nil
		case gt:
			p = part{p.key, ltgt, p.value, p2.value}
		}
	case gt:
		// p2.operator == gt
		if p2.value > p.value {
			return p2, nil
		}
		return p, nil
	}
	// p.operator == ltgt
	if p.value <= p.value2 || p.value == "" {
		return part{}, io.EOF
	}
	if p.value2 == "" {
		return part{p.key, lt, p.value, ""}, nil
	}
	return p, nil
}

// sql returns a SQL expression and a list of arguments for finding records matching p.
func (p part) sql() (sql string, args []interface{}, err error) {
	if p.key == "upload" {
		switch p.operator {
		case equals:
			return "SELECT UploadID, RecordID FROM Records WHERE UploadID = ?", []interface{}{p.value}, nil
		case lt:
			return "SELECT UploadID, RecordID FROM Records WHERE UploadID < ?", []interface{}{p.value}, nil
		case gt:
			return "SELECT UploadID, RecordID FROM Records WHERE UploadID > ?", []interface{}{p.value}, nil
		case ltgt:
			return "SELECT UploadID, RecordID FROM Records WHERE UploadID < ? AND UploadID > ?", []interface{}{p.value, p.value2}, nil
		}
	}
	switch p.operator {
	case equals:
		if p.value == "" {
			// TODO(quentin): Implement support for searching for missing labels.
			return "", nil, fmt.Errorf("missing value for key %q", p.key)
		}
		return "SELECT UploadID, RecordID FROM RecordLabels WHERE Name = ? AND Value = ?", []interface{}{p.key, p.value}, nil
	case lt:
		return "SELECT UploadID, RecordID FROM RecordLabels WHERE Name = ? AND Value < ?", []interface{}{p.key, p.value}, nil
	case gt:
		if p.value == "" {
			// Simplify queries for any value.
			return "SELECT UploadID, RecordID FROM RecordLabels WHERE Name = ?", []interface{}{p.key}, nil
		}
		return "SELECT UploadID, RecordID FROM RecordLabels WHERE Name = ? AND Value > ?", []interface{}{p.key, p.value}, nil
	case ltgt:
		return "SELECT UploadID, RecordID FROM RecordLabels WHERE Name = ? AND Value < ? AND Value > ?", []interface{}{p.key, p.value, p.value2}, nil
	default:
		panic("unknown operator " + string(p.operator))
	}
}
