// 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 (
	"context"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"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, clangFormat, 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.clangFormat, err = findProgram("clang-format", 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"`
	// ClangFormat provides the clang-format binary.
	// https://llvm.googlesource.com/a/llvm-project
	ClangFormat version `json:"clang-format"`
	// 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"`
	// Convert FIDL from old to new (RFC-0050) syntax.
	ConvertSyntax bool `json:"convertSyntax"`
}

// 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 annotationKind = "warning"
	Error   annotationKind = "error"
)

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

// Enumeration of mode values.
const (
	Bytes     mode = "bytes"
	BytesPlus mode = "bytes+"
	C         mode = "c"
	Dart      mode = "dart"
	Diff      mode = "diff"
	FIDL      mode = "fidl"
	FIDLText  mode = "fidltext"
	Go        mode = "go"
	HLCPP     mode = "hlcpp"
	JSON      mode = "json"
	LLCPP     mode = "llcpp"
	Rust      mode = "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:
		switch r.Options.File {
		case "header", "source", "tables":
		default:
			return fmt.Errorf("invalid HLCPP file option: %q", r.Options.File)
		}
	case LLCPP:
		switch r.Options.File {
		case "header", "source", "tables", "test":
		default:
			return fmt.Errorf("invalid LLCPP 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 response{}, fmt.Errorf("invalid input mode: %q", r.InputMode)
}

func (s *server) handleFIDL(ctx context.Context, r *request) (response, error) {
	temp, err := newTempDir()
	if err != nil {
		return response{}, err
	}
	defer os.RemoveAll(temp.path)
	fidl, err := temp.createFile("fidlbolt.fidl", r.Content)
	if err != nil {
		return response{}, err
	}
	libs, anns := s.libraryAnalyzer.analyze(fidl, r.Content)
	res, err := s.handleFIDLWithTemp(ctx, r, temp, fidl, libs)
	if err != nil {
		return res, err
	}
	res.Annotations = append(res.Annotations, anns...)
	// 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, "")
	return res, nil
}

const jsonDepIndentSize = 4

func (s *server) handleFIDLWithTemp(ctx context.Context, r *request, temp tempDir, fidl string, libs libraryMap) (response, error) {
	// Run fidlc, automatically appending the correct --files arguments.
	fidlc := func(args ...string) (response, error) {
		fileArgs, err := libs.fidlcFileArgs()
		if err != nil {
			msg := fmt.Sprintf("%s:1:1: error: %s", fidl, err)
			return response{Ok: false, Content: msg}, nil
		}
		args = append(args, "--experimental", "allow_new_syntax")
		run, err := s.fidlc.run(ctx, append(args, fileArgs...)...)
		if err != nil {
			return response{}, err
		}
		res := response{
			Ok:          run.success,
			Annotations: parseFidlAnnotations(run.stderr),
		}
		if run.success {
			res.Content = run.stdout
		} else {
			res.Content = run.stderr
		}
		return res, nil
	}

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

	switch r.OutputMode {
	case FIDL:
		if r.Options.ConvertSyntax {
			res, err := fidlc("--convert-syntax", temp.path)
			if err != nil {
				return response{}, err
			}
			if !res.Ok {
				return res, nil
			}
			res.Content, err = temp.readFile("fidlbolt.fidl.new")
			if err != nil {
				return response{}, err
			}
			return res, err
		}
		prog := s.fidlFormat
		if r.Options.Lint {
			prog = s.fidlLint
		}
		run, err := prog.run(ctx, fidl)
		if err != nil {
			return response{}, err
		}
		res := response{
			Ok:          run.success,
			Annotations: parseFidlAnnotations(run.stderr),
		}
		if run.success {
			if r.Options.Lint {
				res.Content = "// Lint passed!"
			} else {
				res.Content = run.stdout
			}
		} else {
			res.Content = run.stderr
		}
		return res, nil
	case JSON:
		switch r.Options.File {
		case "ir":
			return fidlc("--json", "/dev/stdout")
		case "schema":
			run, err := s.fidlc.runInfallible(ctx, "--json-schema")
			if err != nil {
				return response{}, err
			}
			return response{Ok: true, Content: run.stdout}, nil
		case "deps":
			graph, err := libs.dependencyGraph()
			if err != nil {
				msg := fmt.Sprintf("%s:1:1: error: %s", fidl, err)
				return response{Ok: false, Content: msg}, 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}, nil
			}
			return response{Ok: true, Content: string(b)}, nil
		default:
			return response{}, fmt.Errorf("invalid file: %q", r.Options.File)
		}
	case C:
		switch r.Options.File {
		case "header":
			return fidlc("--deprecated-fuchsia-only-c-header", "/dev/stdout")
		case "client":
			return fidlc("--deprecated-fuchsia-only-c-client", "/dev/stdout")
		case "server":
			return fidlc("--deprecated-fuchsia-only-c-server", "/dev/stdout")
		default:
			return response{}, fmt.Errorf("invalid file: %q", r.Options.File)
		}
	}

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

func (s *server) handleFIDLWithIR(ctx context.Context, r *request, temp tempDir, jsonIR string) (string, error) {
	switch r.OutputMode {
	case HLCPP:
		if _, err := s.fidlgenHlcpp.runInfallible(ctx,
			"-json", jsonIR,
			"-include-base", temp.path,
			"-output-base", temp.join("impl"),
			"-clang-format-path", s.clangFormat.path,
		); err != nil {
			return "", err
		}
		switch r.Options.File {
		case "header":
			return temp.readFile("impl.h")
		case "source":
			return temp.readFile("impl.cc")
		default:
			return "", fmt.Errorf("invalid file: %q", r.Options.File)
		}
	case LLCPP:
		if _, err := s.fidlgenLlcpp.runInfallible(ctx,
			"-json", jsonIR,
			"-header", temp.join("impl.h"),
			"-source", temp.join("impl.cc"),
			"-test-base", temp.join("test.h"),
			"-clang-format-path", s.clangFormat.path,
		); err != nil {
			return "", err
		}
		switch r.Options.File {
		case "header":
			return temp.readFile("impl.h")
		case "source":
			return temp.readFile("impl.cc")
		case "test":
			return temp.readFile("test.h")
		default:
			return "", fmt.Errorf("invalid file: %q", r.Options.File)
		}
	case Rust:
		if _, err := s.fidlgenRust.runInfallible(ctx,
			"-json", jsonIR,
			"-output-filename", temp.join("impl.rs"),
			"-rustfmt", s.rustfmt.path,
			"-rustfmt-config", s.rustfmtToml,
		); err != nil {
			return "", err
		}
		return temp.readFile("impl.rs")
	case Go:
		if _, err := s.fidlgenGo.runInfallible(ctx,
			"-json", jsonIR,
			"-output-impl", temp.join("impl.go"),
		); err != nil {
			return "", err
		}
		return temp.readFile("impl.go")
	case Dart:
		var name string
		switch r.Options.File {
		case "library":
			name = "async"
		case "test":
			name = "test"
		default:
			return "", fmt.Errorf("invalid file: %q", r.Options.File)
		}
		// TODO(fxbug.dev/70703): Pass -dartfmt.
		if _, err := s.fidlgenDart.runInfallible(ctx,
			"-json", jsonIR,
			"-output-"+name, temp.join("impl.dart"),
		); err != nil {
			return "", err
		}
		return temp.readFile("impl.dart")
	}
	return "", fmt.Errorf("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 response{}, err
		}
		return response{Ok: true, Content: formatted}, nil
	case Diff, FIDLText, BytesPlus:
		return response{Ok: false, Content: "Not implemented"}, nil
	}
	return response{}, fmt.Errorf("invalid output mode: %q", r.OutputMode)
}
