// Copyright 2020 The Fuchsia 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 main

import (
	"bytes"
	"context"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"
)

// A Server handles fidlbolt requests.
type Server struct {
	// External programs used by fidlbolt.
	fidlFormat, fidlLint, fidlc, fidlgenLlcpp, fidlgenHlcpp, fidlgenRust,
	fidlgenGo, fidlgenDart program
	// Cache of FIDL library information.
	libraryAnalyzer *libraryAnalyzer
}

// NewServer returns a new fidlbolt server. It takes two lists of paths: bin,
// for locating binaries, and fidl, for locating FIDL libraries. Returns an
// error if a required program could not be located in bin.
func NewServer(bin, fidl []string) (*Server, error) {
	var s Server
	var err error
	s.fidlFormat, err = findProgram("fidl-format", bin)
	if err != nil {
		return nil, err
	}
	s.fidlLint, err = findProgram("fidl-lint", bin)
	if err != nil {
		return nil, err
	}
	s.fidlc, err = findProgram("fidlc", bin)
	if err != nil {
		return nil, err
	}
	s.fidlgenLlcpp, err = findProgram("fidlgen_llcpp", bin)
	if err != nil {
		return nil, err
	}
	s.fidlgenHlcpp, err = findProgram("fidlgen_hlcpp", bin)
	if err != nil {
		return nil, err
	}
	s.fidlgenRust, err = findProgram("fidlgen_rust", bin)
	if err != nil {
		return nil, err
	}
	s.fidlgenGo, err = findProgram("fidlgen_go", bin)
	if err != nil {
		return nil, err
	}
	s.fidlgenDart, err = findProgram("fidlgen_dart", bin)
	if err != nil {
		return nil, err
	}
	s.libraryAnalyzer = newLibraryAnalyzer(fidl)
	return &s, nil
}

// A Request provides input to be converted to an output mode.
type Request struct {
	// Content to be converted.
	Content string `json:"content"`
	// The mode of Content.
	InputMode Mode `json:"inputMode"`
	// The desired output mode.
	OutputMode Mode `json:"outputMode"`
	// Options for configuring the conversion.
	Options Options `json:"options"`
	// Request context (not serialized).
	ctx context.Context
}

// A Response contains the result of converting to an output mode.
type Response struct {
	// True if conversion was successful.
	Ok bool `json:"ok"`
	// If Ok is true, Content contains the conversion result (in the requested
	// output mode). Otherwise, it contains an error message.
	Content string `json:"content"`
	// List of annotations to apply to on the input.
	Annotations []Annotation `json:"annotations"`
}

// Options are used to configure mode conversions.
type Options struct {
	// File to generate (header, source, etc.).
	File string `json:"file"`
	// Lint in addition to formatting.
	Lint bool `json:"lint"`
	// Number of byte columns.
	Columns int `json:"columns"`
	// Byte grouping size.
	Group int `json:"group"`
	// Use capital letters for hex values.
	Capital bool `json:"capital"`
	// Show byte offsets at the start of each line.
	Offsets bool `json:"offsets"`
	// Show ASCII characters at the end of lines like xxd.
	ASCII bool `json:"ascii"`
}

// An Annotation is a message targeted at a specific location of a file.
type Annotation struct {
	// One-based line number.
	Line int `json:"line"`
	// One-based column number.
	Column int `json:"column"`
	// Kind of annotation.
	Kind AnnotationKind `json:"kind"`
	// Body of the annotation.
	Text string `json:"text"`
}

// AnnotationKind is a string enum for Annotation.
type AnnotationKind string

// Enumeration of AnnotationKind values.
const (
	Info    AnnotationKind = "info"
	Warning                = "warning"
	Error                  = "error"
)

// A Mode is an input or output format.
type Mode string

// Enumeration of Mode values.
const (
	Bytes     Mode = "bytes"
	BytesPlus      = "bytes+"
	C              = "c"
	Dart           = "dart"
	Diff           = "diff"
	FIDL           = "fidl"
	FIDLText       = "fidltext"
	Go             = "go"
	HLCPP          = "hlcpp"
	JSON           = "json"
	LLCPP          = "llcpp"
	Rust           = "rust"
)

type modeSet = map[Mode]struct{}

var inputModes = modeSet{
	FIDL:     {},
	FIDLText: {},
	Bytes:    {},
}

func outputModes(input Mode) modeSet {
	switch input {
	case FIDL:
		return modeSet{
			FIDL:  {},
			JSON:  {},
			C:     {},
			LLCPP: {},
			HLCPP: {},
			Rust:  {},
			Go:    {},
			Dart:  {},
		}
	case FIDLText:
		return modeSet{
			FIDLText:  {},
			Bytes:     {},
			BytesPlus: {},
		}
	case Bytes:
		return modeSet{
			Bytes:     {},
			Diff:      {},
			FIDLText:  {},
			BytesPlus: {},
		}
	}
	return modeSet{}
}

// Validate validates a request. Once validated, any errors in processing the
// request are considered internal server errors.
func (r *Request) Validate() error {
	if err := r.InputMode.validate(inputModes); err != nil {
		return err
	}
	if err := r.OutputMode.validate(outputModes(r.InputMode)); err != nil {
		return err
	}

	switch r.OutputMode {
	case JSON:
		switch r.Options.File {
		case "ir", "schema", "deps":
		default:
			return fmt.Errorf("invalid JSON IR file option: %q", r.Options.File)
		}
	case HLCPP, LLCPP:
		switch r.Options.File {
		case "header", "source", "tables":
		default:
			return fmt.Errorf("invalid C++ file option: %q", r.Options.File)
		}
	case C:
		switch r.Options.File {
		case "header", "client", "server", "tables":
		default:
			return fmt.Errorf("invalid C file option: %q", r.Options.File)
		}
	case Dart:
		switch r.Options.File {
		case "library", "test":
		default:
			return fmt.Errorf("invalid Dart file option: %q", r.Options.File)
		}
	default:
		if r.Options.File != "" {
			return fmt.Errorf("unexpected file option: %q", r.Options.File)
		}
	}

	if r.OutputMode == Bytes {
		if r.Options.Columns <= 0 {
			return fmt.Errorf("invalid columns: %d", r.Options.Columns)
		}
		if r.Options.Group <= 0 {
			return fmt.Errorf("invalid group: %d", r.Options.Group)
		}
	}

	return nil
}

func (m Mode) validate(allowed modeSet) error {
	if _, ok := allowed[m]; !ok {
		return fmt.Errorf("invalid mode: %q", m)
	}
	return nil
}

// Serve processes a request and serves a response. It returns an error if the
// request could not be processed for some reason (e.g., an IO failure).
func (s *Server) Serve(ctx context.Context, r *Request) (Response, error) {
	r.ctx = ctx
	switch r.InputMode {
	case FIDL:
		return s.handleFIDL(r)
	case FIDLText:
		return s.handleFIDLText(r)
	case Bytes:
		return s.handleBytes(r)
	}
	return internalErrorf("invalid input mode: %q", r.InputMode)
}

func (s *Server) handleFIDL(r *Request) (Response, error) {
	temp, err := newTempDir()
	if err != nil {
		return internalError(err)
	}
	defer os.RemoveAll(temp.path)
	res, err := s.handleFIDLWithTemp(r, temp)
	if err != nil {
		return res, err
	}
	// Remove all occurrences of the temp path to avoid exposing it to the user.
	// This is mostly needed for error output, but it is also needed e.g. for
	// the JSON IR, which includes source paths.
	res.Content = strings.ReplaceAll(res.Content, temp.path+"/", "")
	res.Content = strings.ReplaceAll(res.Content, temp.path, "")
	if !res.Ok {
		res.Annotations = append(res.Annotations, parseFidlAnnotations(res.Content)...)
	}
	return res, nil
}

func (s *Server) handleFIDLWithTemp(r *Request, temp tempDir) (Response, error) {
	fidl, err := temp.createFile("fidlbolt.fidl", r.Content)
	if err != nil {
		return internalError(err)
	}

	// Run fidlc, automatically appending the correct --files arguments and
	// producing info annotations for the library declaration and imports.
	fidlc := func(args ...string) Response {
		libs, anns := s.libraryAnalyzer.analyze(fidl, r.Content)
		fileArgs, err := libs.fidlcFileArgs()
		if err != nil {
			msg := fmt.Sprintf("%s:1:1: error: %s", fidl, err)
			return Response{Ok: false, Content: msg, Annotations: anns}
		}
		res := s.fidlc.run(r.ctx, append(args, fileArgs...)...)
		res.Annotations = anns
		return res
	}

	switch r.OutputMode {
	case C, LLCPP, HLCPP:
		if r.Options.File == "tables" {
			return fidlc("--tables", "/dev/stdout"), nil
		}
	}

	switch r.OutputMode {
	case FIDL:
		if r.Options.Lint {
			if res := s.fidlLint.run(r.ctx, fidl); !res.Ok {
				return res, nil
			}
		}
		return s.fidlFormat.run(r.ctx, fidl), nil
	case JSON:
		switch r.Options.File {
		case "ir":
			return fidlc("--json", "/dev/stdout"), nil
		case "schema":
			return s.fidlc.run(r.ctx, "--json-schema"), nil
		case "deps":
			libs, anns := s.libraryAnalyzer.analyze(fidl, r.Content)
			graph, err := libs.jsonDependencyGraph()
			if err != nil {
				msg := fmt.Sprintf("%s:1:1: error: %s", fidl, err)
				return Response{Ok: false, Content: msg, Annotations: anns}, nil
			}
			return Response{Ok: true, Content: graph, Annotations: anns}, nil
		default:
			return internalErrorf("invalid file: %q", r.Options.File)
		}
	case C:
		return fidlc("--c-"+r.Options.File, "/dev/stdout"), nil
	}

	jsonIR := fidl + ".json"
	fidlcRes := fidlc("--json", jsonIR)
	if !fidlcRes.Ok {
		return fidlcRes, nil
	}
	res, err := s.handleFIDLWithIR(r, temp, jsonIR)
	if err != nil {
		return internalError(err)
	}
	res.Annotations = append(res.Annotations, fidlcRes.Annotations...)
	return res, nil
}

func (s *Server) handleFIDLWithIR(r *Request, temp tempDir, jsonIR string) (Response, error) {
	switch r.OutputMode {
	case HLCPP:
		if res := s.fidlgenHlcpp.run(r.ctx,
			"-generators", "cpp",
			"-json", jsonIR,
			"-include-base", temp.path,
			"-output-base", temp.join("impl"),
		); !res.Ok {
			return res, nil
		}
		switch r.Options.File {
		case "header":
			return temp.readFile("impl.h")
		case "source":
			return temp.readFile("impl.cc")
		default:
			return internalErrorf("invalid file: %q", r.Options.File)
		}
	case LLCPP:
		if res := s.fidlgenLlcpp.run(r.ctx,
			"-json", jsonIR,
			"-header", temp.join("impl.h"),
			"-source", temp.join("impl.cc"),
		); !res.Ok {
			return res, nil
		}
		switch r.Options.File {
		case "header":
			return temp.readFile("impl.h")
		case "source":
			return temp.readFile("impl.cc")
		default:
			return internalErrorf("invalid file: %q", r.Options.File)
		}
	case Rust:
		if res := s.fidlgenRust.run(r.ctx,
			"-json", jsonIR,
			"-output-filename", temp.join("impl.rs"),
		); !res.Ok {
			return res, nil
		}
		return temp.readFile("impl.rs")
	case Go:
		if res := s.fidlgenGo.run(r.ctx,
			"-json", jsonIR,
			"-output-impl", temp.join("impl.go"),
		); !res.Ok {
			return res, nil
		}
		return temp.readFile("impl.go")
	case Dart:
		var name string
		switch r.Options.File {
		case "library":
			name = "async"
		case "test":
			name = "test"
		default:
			return internalErrorf("invalid file: %q", r.Options.File)
		}
		if res := s.fidlgenDart.run(r.ctx,
			"-json", jsonIR,
			"-output-"+name, temp.join("impl.dart"),
		); !res.Ok {
			return res, nil
		}
		return temp.readFile("impl.dart")
	}
	return internalErrorf("invalid output mode: %q", r.OutputMode)
}

func (s *Server) handleFIDLText(r *Request) (Response, error) {
	return Response{Ok: false, Content: "Not implemented"}, nil
}

func (s *Server) handleBytes(r *Request) (Response, error) {
	switch r.OutputMode {
	case Bytes:
		b, pos, err := parseBytes(r.Content)
		if err != nil {
			msg := fmt.Sprintf("%s: error: %s", pos, err)
			ann := Annotation{
				Line:   pos.Line,
				Column: pos.Column,
				Kind:   Error,
				Text:   err.Error(),
			}
			return Response{Ok: false, Content: msg, Annotations: []Annotation{ann}}, nil
		}
		formatted, err := formatBytes(b, &r.Options)
		if err != nil {
			return internalError(err)
		}
		return Response{Ok: true, Content: formatted}, nil
	case Diff, FIDLText, BytesPlus:
		return Response{Ok: false, Content: "Not implemented"}, nil
	}
	return internalErrorf("invalid output mode: %q", r.OutputMode)
}

// internalError reports an internal server error.
func internalError(err error) (Response, error) {
	return Response{}, err
}

// internalErrorf is like internalError but takes fmt.Printf arguments.
func internalErrorf(format string, a ...interface{}) (Response, error) {
	return internalError(fmt.Errorf(format, a...))
}

// program represents an external program by its executable path.
type program struct {
	path string
}

// findProgram searches the directories in bin for the named program. It returns
// an error if the program cannot be found.
func findProgram(name string, bin []string) (program, error) {
	for _, dir := range bin {
		path := filepath.Join(dir, name)
		if _, err := os.Stat(path); err == nil {
			return program{path}, nil
		}
	}
	return program{}, fmt.Errorf("cannot find program: %q", name)
}

// run runs a program with arguments and produces a response. It stops the
// program and returns if ctx is cancelled.
func (p program) run(ctx context.Context, arg ...string) Response {
	// TODO: use exec.CommandContext!
	cmd := exec.Command(p.path, arg...)
	var out bytes.Buffer
	cmd.Stdout = &out
	cmd.Stderr = &out
	if err := cmd.Start(); err != nil {
		msg := fmt.Sprintf("Failed to execute %s", filepath.Base(p.path))
		return Response{Ok: false, Content: msg}
	}
	result := make(chan error, 1)
	go func() {
		result <- cmd.Wait()
	}()
	select {
	case <-ctx.Done():
		if err := cmd.Process.Kill(); err != nil {
			log.Printf("Failed to kill process %s with pid %d", p.path, cmd.Process.Pid)
		}
		// The response doesn't matter, since http.TimeoutHandler will respond
		// with 503 Service Unavailable after cancelling ctx.
		return Response{Ok: false}
	case err := <-result:
		return Response{
			Ok:      err == nil,
			Content: out.String(),
		}
	}
}

// A tempDir is temporary directory.
type tempDir struct {
	path string
}

// newTempDir creates a new temporary directory.
func newTempDir() (tempDir, error) {
	path, err := ioutil.TempDir("", "fidlbolt-")
	return tempDir{path}, err
}

// join returns a path inside the temporary directory.
func (d tempDir) join(elem ...string) string {
	elem = append([]string{d.path}, elem...)
	return filepath.Join(elem...)
}

// createFile creates a file in the temporary directory, writes content to it,
// and returns its path.
func (d tempDir) createFile(name, content string) (string, error) {
	f, err := os.Create(d.join(name))
	if err != nil {
		return "", err
	}
	if _, err = f.WriteString(content); err != nil {
		return "", err
	}
	f.Close()
	return f.Name(), nil
}

// readFile creates a response from a file in the temporary directory.
func (d tempDir) readFile(name string) (Response, error) {
	b, err := ioutil.ReadFile(d.join(name))
	if err != nil {
		return Response{}, err
	}
	return Response{Ok: true, Content: string(b)}, nil
}

var fidlAnnotationRegexp = regexp.MustCompile(
	`(?m)^fidlbolt\.fidl:(\d+):(\d+).*?(info|error|warning):\s*(.*)$`)

// parseFidlAnnotations parses a list of annotations from error output. It
// assumes that the output refers to a file called "fidlbolt.fidl".
func parseFidlAnnotations(output string) []Annotation {
	matches := fidlAnnotationRegexp.FindAllStringSubmatch(output, -1)
	var anns []Annotation
	for _, m := range matches {
		line, err := strconv.Atoi(m[1])
		if err != nil {
			continue
		}
		column, err := strconv.Atoi(m[2])
		if err != nil {
			continue
		}
		anns = append(anns, Annotation{
			Line:   line,
			Column: column,
			Kind:   AnnotationKind(m[3]),
			Text:   m[4],
		})
	}
	return anns
}
