// 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"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"
)

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

// NewServer returns a new fidlbolt server. It takes three lists of paths: bin,
// for locating binaries, etc, for locating config files, and fidl, for locating
// FIDL libraries. Returns an error if a required file could not be located.
func NewServer(bin, etc, fidl []string) (*Server, error) {
	var s Server
	var err error
	if deploymentFile, err := findFile("fidlbolt_deployment.json", etc); err == nil {
		deploymentBytes, err := ioutil.ReadFile(deploymentFile)
		if err != nil {
			return nil, fmt.Errorf("failed to read etc/fidlbolt_deployment.json: %s", err)
		}
		s.deployment = new(Deployment)
		if err = json.Unmarshal(deploymentBytes, s.deployment); err != nil {
			return nil, fmt.Errorf("failed to parse etc/fidlbolt_deployment.json: %s", err)
		}
	}
	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.rustfmt, err = findProgram("rustfmt", bin)
	if err != nil {
		return nil, err
	}
	s.rustfmtToml, err = findFile("rustfmt.toml", etc)
	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"`
}

// 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"`
	// Information about the deployment that served this response.
	Deployment *Deployment `json:"deployment,omitempty"`
}

// A Deployment describes the provenance of all resources used to service a
// request, including the fidlbolt server itself, external binaries, FIDL
// libaries, configuration files, etc.
type Deployment struct {
	// This repository.
	// https://fuchsia.googlesource.com/fidlbolt
	Fidlbolt Commit `json:"fidlbolt"`
	// Fuchsia provides most resources used by fidlbolt.
	// https://fuchsia.googlesource.com/fuchsia
	Fuchsia Commit `json:"fuchsia"`
	// Topaz provides the fidlgen_dart binary.
	// https://fuchsia.googlesource.com/topaz
	Topaz Commit `json:"topaz"`
	// Rustfmt provides the rustfmt binary.
	// https://github.com/rust-lang/rustfmt
	Rustfmt Version `json:"rustfmt"`
}

// A Commit designates a commit in a source code repository.
type Commit struct {
	// Full hash of the commit.
	Hash string `json:"hash"`
	// Unix timestamp of the commit, in seconds.
	Timestamp uint64 `json:"timestamp"`
}

// A Version designates a software version by a string like "1.2.3".
type Version struct {
	Version string `json:"version"`
}

// 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:    {},
}

var outputModes = map[Mode]modeSet{
	FIDL: {
		FIDL:  {},
		JSON:  {},
		C:     {},
		LLCPP: {},
		HLCPP: {},
		Rust:  {},
		Go:    {},
		Dart:  {},
	},
	FIDLText: {
		FIDLText:  {},
		Bytes:     {},
		BytesPlus: {},
	},
	Bytes: {
		Bytes:     {},
		Diff:      {},
		FIDLText:  {},
		BytesPlus: {},
	},
}

// 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) {
	res, err := s.handle(ctx, r)
	if err != nil {
		return Response{}, err
	}
	res.Deployment = s.deployment
	return res, nil
}

func (s *Server) handle(ctx context.Context, r *Request) (Response, error) {
	switch r.InputMode {
	case FIDL:
		return s.handleFIDL(ctx, r)
	case FIDLText:
		return s.handleFIDLText(ctx, r)
	case Bytes:
		return s.handleBytes(ctx, r)
	}
	return internalErrorf("invalid input mode: %q", r.InputMode)
}

func (s *Server) handleFIDL(ctx context.Context, r *Request) (Response, error) {
	temp, err := newTempDir()
	if err != nil {
		return internalError(err)
	}
	defer os.RemoveAll(temp.path)
	res, err := s.handleFIDLWithTemp(ctx, 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
}

const jsonDepIndentSize = 4

func (s *Server) handleFIDLWithTemp(ctx context.Context, 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(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(ctx, fidl); !res.Ok {
				return res, nil
			}
			return Response{Ok: true, Content: "// Lint passed!"}, nil
		}
		return s.fidlFormat.run(ctx, fidl), nil
	case JSON:
		switch r.Options.File {
		case "ir":
			return fidlc("--json", "/dev/stdout"), nil
		case "schema":
			return s.fidlc.run(ctx, "--json-schema"), nil
		case "deps":
			libs, anns := s.libraryAnalyzer.analyze(fidl, r.Content)
			graph, err := libs.dependencyGraph()
			if err != nil {
				msg := fmt.Sprintf("%s:1:1: error: %s", fidl, err)
				return Response{Ok: false, Content: msg, Annotations: anns}, nil
			}
			b, err := json.MarshalIndent(graph, "", strings.Repeat(" ", jsonDepIndentSize))
			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: string(b), Annotations: anns}, nil
		default:
			return internalErrorf("invalid file: %q", r.Options.File)
		}
	case C:
		switch r.Options.File {
		case "header":
			return fidlc("--fuchsia-only-c-header", "/dev/stdout"), nil
		case "client":
			return fidlc("--fuchsia-only-c-client", "/dev/stdout"), nil
		case "server":
			return fidlc("--fuchsia-only-c-server", "/dev/stdout"), nil
		default:
			return internalErrorf("invalid file: %q", r.Options.File)
		}
	}

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

func (s *Server) handleFIDLWithIR(ctx context.Context, r *Request, temp tempDir, jsonIR string) (Response, error) {
	switch r.OutputMode {
	case HLCPP:
		if res := s.fidlgenHlcpp.run(ctx,
			"-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(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(ctx,
			"-json", jsonIR,
			"-output-filename", temp.join("impl.rs"),
			"-rustfmt", s.rustfmt.path,
			"-rustfmt-config", s.rustfmtToml,
		); !res.Ok {
			return res, nil
		}
		return temp.readFile("impl.rs")
	case Go:
		if res := s.fidlgenGo.run(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(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(ctx context.Context, r *Request) (Response, error) {
	return Response{Ok: false, Content: "Not implemented"}, nil
}

func (s *Server) handleBytes(ctx context.Context, 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) {
	path, err := findFile(name, bin)
	return program{path}, err
}

// findFile searches the directories in dirs for the file with the given name.
// It returns the full path, or an error if the file cannot be found.
func findFile(name string, dirs []string) (string, error) {
	for _, dir := range dirs {
		path := filepath.Join(dir, name)
		if _, err := os.Stat(path); err == nil {
			return path, nil
		}
	}
	return "", fmt.Errorf("cannot find %s (searched in %s)", name, strings.Join(dirs, ", "))
}

// run runs a program with arguments and produces a response. It stops the
// program and returns if ctx is cancelled.
// TODO: Consider returning a string and error here, and letting the top-level
// handlers produce responses instead.
func (p program) run(ctx context.Context, arg ...string) Response {
	cmd := exec.CommandContext(ctx, p.path, arg...)
	var out bytes.Buffer
	cmd.Stdout = &out
	cmd.Stderr = &out
	switch err := cmd.Run().(type) {
	case nil, *exec.ExitError:
		return Response{
			Ok:      err == nil,
			Content: out.String(),
		}
	default:
		msg := fmt.Sprintf("Failed to execute %s", filepath.Base(p.path))
		return Response{Ok: false, Content: msg}
	}
}

// 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
	}
	defer f.Close()
	if _, err = f.WriteString(content); err != nil {
		return "", err
	}
	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(`` +
	// Multi-line mode: ^ and $ match begin/end of line OR text.
	`(?m)` +
	`^fidlbolt\.fidl:(\d+):(\d+).*?` +
	`(` +
	string(Info) + `|` +
	string(Warning) + `|` +
	string(Error) + `)` +
	`:\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
}
