// Copyright (c) 2019, Google Inc.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

//go:build interactive
// +build interactive

package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	neturl "net/url"
	"os"
	"os/exec"
	"os/signal"
	"path/filepath"
	"reflect"
	"strconv"
	"strings"
	"syscall"

	"boringssl.googlesource.com/boringssl/util/fipstools/acvp/acvptool/acvp"
	"golang.org/x/crypto/ssh/terminal"
)

const interactiveModeSupported = true

func updateTerminalSize(term *terminal.Terminal) {
	width, height, err := terminal.GetSize(0)
	if err != nil {
		return
	}
	term.SetSize(width, height)
}

func skipWS(node *node32) *node32 {
	for ; node != nil && node.pegRule == ruleWS; node = node.next {
	}
	return node
}

func assertNodeType(node *node32, rule pegRule) {
	if node.pegRule != rule {
		panic(fmt.Sprintf("expected %q, found %q", rul3s[rule], rul3s[node.pegRule]))
	}
}

type Object interface {
	String() (string, error)
	Index(string) (Object, error)
	Search(acvp.Query) (Object, error)
	Action(action string, args []string) error
}

type ServerObjectSet struct {
	env          *Env
	name         string
	searchKeys   map[string][]acvp.Relation
	resultType   reflect.Type
	subObjects   map[string]func(*Env, string) (Object, error)
	canEnumerate bool
}

func (set ServerObjectSet) String() (string, error) {
	if !set.canEnumerate {
		return "[object set " + set.name + "]", nil
	}

	data := reflect.New(reflect.SliceOf(set.resultType)).Interface()
	if err := set.env.server.GetPaged(data, "acvp/v1/"+set.name, nil); err != nil {
		return "", err
	}
	ret, err := json.MarshalIndent(data, "", "  ")
	return string(ret), err
}

func (set ServerObjectSet) Index(indexStr string) (Object, error) {
	index, err := strconv.ParseUint(indexStr, 0, 64)
	if err != nil {
		return nil, fmt.Errorf("object set indexes must be unsigned integers, trying to parse %q failed: %s", indexStr, err)
	}
	return ServerObject{&set, index}, nil
}

func (set ServerObjectSet) Search(condition acvp.Query) (Object, error) {
	if set.searchKeys == nil {
		return nil, errors.New("this object set cannot be searched")
	}

	for _, conj := range condition {
	NextCondition:
		for _, cond := range conj {
			allowed, ok := set.searchKeys[cond.Param]
			if !ok {
				return nil, fmt.Errorf("search key %q not valid for this object set", cond.Param)
			}

			for _, rel := range allowed {
				if rel == cond.Relation {
					continue NextCondition
				}
			}

			return nil, fmt.Errorf("search key %q cannot be used with relation %q", cond.Param, cond.Relation.String())
		}
	}

	return Search{ServerObjectSet: set, query: condition}, nil
}

func (set ServerObjectSet) Action(action string, args []string) error {
	switch action {
	default:
		return fmt.Errorf("unknown action %q", action)

	case "new":
		if len(args) != 0 {
			return fmt.Errorf("found %d arguments but %q takes none", len(args), action)
		}

		newContents, err := edit("")
		if err != nil {
			return err
		}

		if strings.TrimSpace(string(newContents)) == "" {
			io.WriteString(set.env.term, "Resulting file was empty. Ignoring.\n")
			return nil
		}

		var result map[string]interface{}
		if err := set.env.server.Post(&result, "acvp/v1/"+set.name, newContents); err != nil {
			return err
		}

		// In case it's a testSession that was just created, poke any access token
		// into the server's lookup table and the cache.
		if urlInterface, ok := result["url"]; ok {
			if url, ok := urlInterface.(string); ok {
				if tokenInterface, ok := result["accessToken"]; ok {
					if token, ok := tokenInterface.(string); ok {
						for strings.HasPrefix(url, "/") {
							url = url[1:]
						}
						set.env.server.PrefixTokens[url] = token
						if len(set.env.config.SessionTokensCache) > 0 {
							os.WriteFile(filepath.Join(set.env.config.SessionTokensCache, neturl.PathEscape(url))+".token", []byte(token), 0600)
						}
					}
				}
			}
		}

		ret, err := json.MarshalIndent(result, "", "  ")
		if err != nil {
			return err
		}
		set.env.term.Write(ret)
		return nil
	}
}

type ServerObject struct {
	set   *ServerObjectSet
	index uint64
}

func (obj ServerObject) String() (string, error) {
	data := reflect.New(obj.set.resultType).Interface()
	if err := obj.set.env.server.Get(data, "acvp/v1/"+obj.set.name+"/"+strconv.FormatUint(obj.index, 10)); err != nil {
		return "", err
	}
	ret, err := json.MarshalIndent(data, "", "  ")
	return string(ret), err
}

func (obj ServerObject) Index(index string) (Object, error) {
	if obj.set.subObjects == nil {
		return nil, errors.New("cannot index " + obj.set.name + " objects")
	}
	constr, ok := obj.set.subObjects[index]
	if !ok {
		return nil, fmt.Errorf("no such subobject %q", index)
	}
	return constr(obj.set.env, fmt.Sprintf("%s/%d", obj.set.name, obj.index))
}

func (ServerObject) Search(condition acvp.Query) (Object, error) {
	return nil, errors.New("cannot search individual object")
}

func edit(initialContents string) ([]byte, error) {
	tmp, err := os.CreateTemp("", "acvp*.json")
	if err != nil {
		return nil, err
	}
	path := tmp.Name()
	defer os.Remove(path)

	_, err = io.WriteString(tmp, initialContents)
	tmp.Close()
	if err != nil {
		return nil, err
	}

	editor := os.Getenv("EDITOR")
	if len(editor) == 0 {
		editor = "vim"
	}

	cmd := exec.Command(editor, path)
	cmd.Stdout = os.Stdout
	cmd.Stdin = os.Stdin
	cmd.Stderr = os.Stderr
	if err := cmd.Run(); err != nil {
		return nil, err
	}

	return os.ReadFile(path)
}

func (obj ServerObject) Action(action string, args []string) error {
	switch action {
	default:
		return fmt.Errorf("unknown action %q", action)

	case "edit":
		if len(args) != 0 {
			return fmt.Errorf("found %d arguments but %q takes none", len(args), action)
		}

		contents, err := obj.String()
		if err != nil {
			return err
		}

		newContents, err := edit(contents)
		if err != nil {
			return err
		}

		if trimmed := strings.TrimSpace(string(newContents)); len(trimmed) == 0 || trimmed == strings.TrimSpace(contents) {
			io.WriteString(obj.set.env.term, "Resulting file was equal or empty. Not updating.\n")
			return nil
		}

		var status acvp.RequestStatus
		if err := obj.set.env.server.Put(&status, "acvp/v1/"+obj.set.name+"/"+strconv.FormatUint(obj.index, 10), newContents); err != nil {
			return err
		}

		fmt.Fprintf(obj.set.env.term, "%#v\n", status)
		return nil

	case "delete":
		if len(args) != 0 {
			return fmt.Errorf("found %d arguments but %q takes none", len(args), action)
		}
		return obj.set.env.server.Delete("acvp/v1/" + obj.set.name + "/" + strconv.FormatUint(obj.index, 10))
	}
}

type Search struct {
	ServerObjectSet
	query acvp.Query
}

func (search Search) String() (string, error) {
	data := reflect.New(reflect.SliceOf(search.resultType)).Interface()
	fmt.Printf("Searching for %#v\n", search.query)
	if err := search.env.server.GetPaged(data, "acvp/v1/"+search.name, search.query); err != nil {
		return "", err
	}
	ret, err := json.MarshalIndent(data, "", "  ")
	return string(ret), err
}

func (search Search) Index(_ string) (Object, error) {
	return nil, errors.New("indexing of search results not supported")
}

func (search Search) Search(condition acvp.Query) (Object, error) {
	search.query = append(search.query, condition...)
	return search, nil
}

func (Search) Action(_ string, _ []string) error {
	return errors.New("no actions supported on search objects")
}

type Algorithms struct {
	ServerObjectSet
}

func (algos Algorithms) String() (string, error) {
	var result struct {
		Algorithms []map[string]interface{} `json:"algorithms"`
	}
	if err := algos.env.server.Get(&result, "acvp/v1/algorithms"); err != nil {
		return "", err
	}
	ret, err := json.MarshalIndent(result.Algorithms, "", "  ")
	return string(ret), err
}

type Env struct {
	line      string
	variables map[string]Object
	server    *acvp.Server
	term      *terminal.Terminal
	config    Config
}

func (e *Env) bytes(node *node32) []byte {
	return []byte(e.line[node.begin:node.end])
}

func (e *Env) contents(node *node32) string {
	return e.line[node.begin:node.end]
}

type stringLiteral struct {
	env      *Env
	contents string
}

func (s stringLiteral) String() (string, error) {
	return s.contents, nil
}

func (stringLiteral) Index(_ string) (Object, error) {
	return nil, errors.New("cannot index strings")
}

func (stringLiteral) Search(_ acvp.Query) (Object, error) {
	return nil, errors.New("cannot search strings")
}

func (s stringLiteral) Action(action string, args []string) error {
	switch action {
	default:
		return fmt.Errorf("action %q not supported on string literals", action)

	case "GET":
		if len(args) != 0 {
			return fmt.Errorf("found %d arguments but %q takes none", len(args), action)
		}

		var results map[string]interface{}
		if err := s.env.server.Get(&results, s.contents); err != nil {
			return err
		}
		ret, err := json.MarshalIndent(results, "", "  ")
		if err != nil {
			return err
		}
		s.env.term.Write(ret)
		return nil
	}
}

type results struct {
	env    *Env
	prefix string
}

func (r results) String() (string, error) {
	var results map[string]interface{}
	if err := r.env.server.Get(&results, "acvp/v1/"+r.prefix+"/results"); err != nil {
		return "", err
	}
	ret, err := json.MarshalIndent(results, "", "  ")
	return string(ret), err
}

func (results) Index(_ string) (Object, error) {
	return nil, errors.New("cannot index results objects")
}

func (results) Search(_ acvp.Query) (Object, error) {
	return nil, errors.New("cannot search results objects")
}

func (results) Action(_ string, _ []string) error {
	return errors.New("no actions supported on results objects")
}

func (e *Env) parseStringLiteral(node *node32) string {
	assertNodeType(node, ruleStringLiteral)
	in := e.bytes(node)
	var buf bytes.Buffer
	for i := 1; i < len(in)-1; i++ {
		if in[i] == '\\' {
			switch in[i+1] {
			case '\\':
				buf.WriteByte('\\')
			case 'n':
				buf.WriteByte('\n')
			case '"':
				buf.WriteByte('"')
			default:
				panic("unknown escape")
			}
			i++
			continue
		}
		buf.WriteByte(in[i])
	}

	return buf.String()
}

func (e *Env) evalExpression(node *node32) (obj Object, err error) {
	switch node.pegRule {
	case ruleStringLiteral:
		return stringLiteral{e, e.parseStringLiteral(node)}, nil

	case ruleVariable:
		varName := e.contents(node)
		obj, ok := e.variables[varName]
		if !ok {
			return nil, fmt.Errorf("unknown variable %q", varName)
		}
		return obj, nil

	case ruleIndexing:
		node = node.up
		assertNodeType(node, ruleVariable)
		varName := e.contents(node)
		obj, ok := e.variables[varName]
		if !ok {
			return nil, fmt.Errorf("unknown variable %q", varName)
		}

		node = node.next
		for node != nil {
			assertNodeType(node, ruleIndex)
			indexStr := e.contents(node)
			if obj, err = obj.Index(indexStr); err != nil {
				return nil, err
			}
			node = node.next
		}

		return obj, nil

	case ruleSearch:
		node = node.up
		assertNodeType(node, ruleVariable)
		varName := e.contents(node)
		obj, ok := e.variables[varName]
		if !ok {
			return nil, fmt.Errorf("unknown variable %q", varName)
		}

		node = skipWS(node.next)
		assertNodeType(node, ruleQuery)
		node = node.up

		var query acvp.Query
		for node != nil {
			assertNodeType(node, ruleConjunctions)
			query = append(query, e.parseConjunction(node.up))
			node = skipWS(node.next)
		}

		if len(query) == 0 {
			return nil, errors.New("cannot have empty query")
		}

		return obj.Search(query)
	}

	panic("unhandled")
}

func (e *Env) evalAction(node *node32) error {
	assertNodeType(node, ruleExpression)
	obj, err := e.evalExpression(node.up)
	if err != nil {
		return err
	}

	node = node.next
	assertNodeType(node, ruleCommand)
	node = node.up
	assertNodeType(node, ruleFunction)
	function := e.contents(node)
	node = node.next

	var args []string
	for node != nil {
		assertNodeType(node, ruleArgs)
		node = node.up
		args = append(args, e.parseStringLiteral(node))

		node = skipWS(node.next)
	}

	return obj.Action(function, args)
}

func (e *Env) parseConjunction(node *node32) (ret acvp.Conjunction) {
	for node != nil {
		assertNodeType(node, ruleConjunction)
		ret = append(ret, e.parseCondition(node.up))

		node = skipWS(node.next)
		if node != nil {
			assertNodeType(node, ruleConjunctions)
			node = node.up
		}
	}
	return ret
}

func (e *Env) parseCondition(node *node32) (ret acvp.Condition) {
	assertNodeType(node, ruleField)
	ret.Param = e.contents(node)
	node = skipWS(node.next)

	assertNodeType(node, ruleRelation)
	switch e.contents(node) {
	case "==":
		ret.Relation = acvp.Equals
	case "!=":
		ret.Relation = acvp.NotEquals
	case "contains":
		ret.Relation = acvp.Contains
	case "startsWith":
		ret.Relation = acvp.StartsWith
	case "endsWith":
		ret.Relation = acvp.EndsWith
	default:
		panic("relation not handled: " + e.contents(node))
	}
	node = skipWS(node.next)

	ret.Value = e.parseStringLiteral(node)

	return ret
}

func runInteractive(server *acvp.Server, config Config) {
	oldState, err := terminal.MakeRaw(0)
	if err != nil {
		panic(err)
	}
	defer terminal.Restore(0, oldState)
	term := terminal.NewTerminal(os.Stdin, "> ")

	resizeChan := make(chan os.Signal, 1)
	go func() {
		for _ = range resizeChan {
			updateTerminalSize(term)
		}
	}()
	signal.Notify(resizeChan, syscall.SIGWINCH)

	env := &Env{variables: make(map[string]Object), server: server, term: term, config: config}
	env.variables["requests"] = ServerObjectSet{
		env:          env,
		name:         "requests",
		resultType:   reflect.TypeOf(&acvp.RequestStatus{}),
		canEnumerate: true,
	}
	env.variables["vendors"] = ServerObjectSet{
		env:  env,
		name: "vendors",
		searchKeys: map[string][]acvp.Relation{
			"name":        []acvp.Relation{acvp.Equals, acvp.StartsWith, acvp.EndsWith, acvp.Contains},
			"website":     []acvp.Relation{acvp.Equals, acvp.StartsWith, acvp.EndsWith, acvp.Contains},
			"email":       []acvp.Relation{acvp.Equals, acvp.StartsWith, acvp.EndsWith, acvp.Contains},
			"phoneNumber": []acvp.Relation{acvp.Equals, acvp.StartsWith, acvp.EndsWith, acvp.Contains},
		},
		subObjects: map[string]func(*Env, string) (Object, error){
			"contacts": func(env *Env, prefix string) (Object, error) {
				return ServerObjectSet{
					env:          env,
					name:         prefix + "/contacts",
					resultType:   reflect.TypeOf(&acvp.Person{}),
					canEnumerate: true,
				}, nil
			},
			"addresses": func(env *Env, prefix string) (Object, error) {
				return ServerObjectSet{
					env:          env,
					name:         prefix + "/addresses",
					resultType:   reflect.TypeOf(&acvp.Address{}),
					canEnumerate: true,
				}, nil
			},
		},
		resultType: reflect.TypeOf(&acvp.Vendor{}),
	}
	env.variables["persons"] = ServerObjectSet{
		env:  env,
		name: "persons",
		searchKeys: map[string][]acvp.Relation{
			"fullName":    []acvp.Relation{acvp.Equals, acvp.StartsWith, acvp.EndsWith, acvp.Contains},
			"email":       []acvp.Relation{acvp.Equals, acvp.StartsWith, acvp.EndsWith, acvp.Contains},
			"phoneNumber": []acvp.Relation{acvp.Equals, acvp.StartsWith, acvp.EndsWith, acvp.Contains},
			"vendorId":    []acvp.Relation{acvp.Equals, acvp.NotEquals, acvp.LessThan, acvp.LessThanEqual, acvp.GreaterThan, acvp.GreaterThanEqual},
		},
		resultType: reflect.TypeOf(&acvp.Person{}),
	}
	env.variables["modules"] = ServerObjectSet{
		env:  env,
		name: "modules",
		searchKeys: map[string][]acvp.Relation{
			"name":        []acvp.Relation{acvp.Equals, acvp.StartsWith, acvp.EndsWith, acvp.Contains},
			"version":     []acvp.Relation{acvp.Equals, acvp.StartsWith, acvp.EndsWith, acvp.Contains},
			"website":     []acvp.Relation{acvp.Equals, acvp.StartsWith, acvp.EndsWith, acvp.Contains},
			"description": []acvp.Relation{acvp.Equals, acvp.StartsWith, acvp.EndsWith, acvp.Contains},
			"type":        []acvp.Relation{acvp.Equals, acvp.NotEquals},
			"vendorId":    []acvp.Relation{acvp.Equals, acvp.NotEquals, acvp.LessThan, acvp.LessThanEqual, acvp.GreaterThan, acvp.GreaterThanEqual},
		},
		resultType: reflect.TypeOf(&acvp.Module{}),
	}
	env.variables["oes"] = ServerObjectSet{
		env:  env,
		name: "oes",
		searchKeys: map[string][]acvp.Relation{
			"name": []acvp.Relation{acvp.Equals, acvp.StartsWith, acvp.EndsWith, acvp.Contains},
		},
		resultType: reflect.TypeOf(&acvp.OperationalEnvironment{}),
	}
	env.variables["deps"] = ServerObjectSet{
		env:  env,
		name: "dependencies",
		searchKeys: map[string][]acvp.Relation{
			"name":        []acvp.Relation{acvp.Equals, acvp.StartsWith, acvp.EndsWith, acvp.Contains},
			"type":        []acvp.Relation{acvp.Equals, acvp.StartsWith, acvp.EndsWith, acvp.Contains},
			"description": []acvp.Relation{acvp.Equals, acvp.StartsWith, acvp.EndsWith, acvp.Contains},
		},
		resultType: reflect.TypeOf(&acvp.Dependency{}),
	}
	env.variables["algos"] = Algorithms{
		ServerObjectSet{
			env:          env,
			name:         "algorithms",
			resultType:   reflect.TypeOf(&acvp.Algorithm{}),
			canEnumerate: true,
		},
	}
	env.variables["sessions"] = ServerObjectSet{
		env:          env,
		name:         "testSessions",
		resultType:   reflect.TypeOf(&acvp.TestSession{}),
		canEnumerate: true,
		subObjects: map[string]func(env *Env, prefix string) (Object, error){
			"results": func(env *Env, prefix string) (Object, error) {
				return results{env: env, prefix: prefix}, nil
			},
		},
	}

	for {
		if env.line, err = term.ReadLine(); err != nil {
			return
		}
		if len(env.line) == 0 {
			continue
		}

		stmt := Statement{Buffer: env.line, Pretty: true}
		stmt.Init()
		if err := stmt.Parse(); err != nil {
			io.WriteString(term, err.Error())
			continue
		}

		node := skipWS(stmt.AST().up)
		switch node.pegRule {
		case ruleExpression:
			obj, err := env.evalExpression(node.up)
			var repr string
			if err == nil {
				repr, err = obj.String()
			}

			if err != nil {
				fmt.Fprintf(term, "error while evaluating expression: %s\n", err)
			} else {
				io.WriteString(term, repr)
				io.WriteString(term, "\n")
			}

		case ruleAction:
			if err := env.evalAction(node.up); err != nil {
				io.WriteString(term, err.Error())
				io.WriteString(term, "\n")
			}

		default:
			fmt.Fprintf(term, "internal error parsing input.\n")
		}
	}
}
