// 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 (
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"time"
)

var (
	portFlag    = flag.String("port", "", "port to serve on")
	verboseFlag = flag.Bool("verbose", false, "enable verbose logging")
	staticFlag  = flag.String("static", "", "static files directory")
	binFlag     = flag.String("bin", "", "binary search paths, "+pathHelp)
	etcFlag     = flag.String("etc", "", "config file search paths, "+pathHelp)
	fidlFlag    = flag.String("fidl", "", "FIDL library search paths, "+pathHelp)

	pathHelp = fmt.Sprintf(`separated by "%s"`, string(filepath.ListSeparator))
)

func printUsage() {
	program := filepath.Base(os.Args[0])
	message :=
		`Usage: ` + program + ` [flags]

Web server for fidlbolt, a tool for exploring FIDL code and bytes

Flags:
`

	fmt.Fprint(flag.CommandLine.Output(), message)
	flag.PrintDefaults()
}

func main() {
	flag.Usage = printUsage
	flag.Parse()

	// Remove timestamps from logs for startup error messages.
	log.SetFlags(0)

	static := *staticFlag
	bin := filepath.SplitList(*binFlag)
	etc := filepath.SplitList(*etcFlag)
	fidl := filepath.SplitList(*fidlFlag)
	if static == "" || len(bin) == 0 || len(etc) == 0 || len(fidl) == 0 {
		log.Print("must provide -static, -bin, -etc, and -fidl")
		printUsage()
		os.Exit(1)
	}
	checkDirs(static)
	checkDirs(bin...)
	checkDirs(etc...)
	checkDirs(fidl...)

	server, err := newServer(bin, etc, fidl)
	if err != nil {
		log.Fatal(err)
	}

	mux := http.NewServeMux()
	mux.Handle("/", http.FileServer(http.Dir(static)))
	mux.Handle("/convert", &postHandler{server, *verboseFlag})

	timeout := 10 * time.Second
	handler := http.TimeoutHandler(
		mux, timeout, fmt.Sprintf("Request exceeded the %v time limit", timeout))
	handler = logging(handler)

	port := *portFlag
	if port == "" {
		port = os.Getenv("PORT")
		if port == "" {
			port = "8080"
		}
	}

	s := &http.Server{
		Addr:         ":" + port,
		Handler:      handler,
		ReadTimeout:  10 * time.Second,
		WriteTimeout: timeout + 5*time.Second,
	}
	log.Printf("Listening on %s", s.Addr)
	log.SetFlags(log.LstdFlags)
	log.Fatal(s.ListenAndServe())
}

type postHandler struct {
	server  *server
	verbose bool
}

func (h *postHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		writeError(w, http.StatusMethodNotAllowed, nil)
		return
	}
	if r.Body == nil {
		writeError(w, http.StatusBadRequest, nil)
		return
	}
	var request request
	if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
		writeError(w, http.StatusBadRequest, err)
		return
	}
	if h.verbose {
		log.Printf("Request body: %#v", request)
	}
	if err := request.validate(); err != nil {
		writeError(w, http.StatusUnprocessableEntity, err)
		return
	}
	response, err := h.server.serve(r.Context(), &request)
	if err != nil {
		writeError(w, http.StatusInternalServerError, err)
		return
	}
	body, err := json.Marshal(response)
	if err != nil {
		writeError(w, http.StatusInternalServerError, err)
		return
	}
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	w.Write(body)
}

func checkDirs(dirs ...string) {
	for _, dir := range dirs {
		if _, err := os.Stat(dir); os.IsNotExist(err) {
			log.Fatalf("%s: directory does not exist", dir)
		}
	}
}

type statusWriter struct {
	http.ResponseWriter
	status int
}

func (sw *statusWriter) WriteHeader(status int) {
	sw.status = status
	sw.ResponseWriter.WriteHeader(status)
}

func logging(handler http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		log.Printf("[%s] %s %s", r.RemoteAddr, r.Method, r.URL)
		sw := statusWriter{ResponseWriter: w}
		handler.ServeHTTP(&sw, r)
		log.Printf("[%s] -> %d %s", r.RemoteAddr, sw.status, http.StatusText(sw.status))
	})
}

func writeError(w http.ResponseWriter, code int, err error) {
	text := fmt.Sprintf("%d %s", code, http.StatusText(code))
	http.Error(w, text, code)
	if err != nil {
		log.Printf("ERROR: %s", err.Error())
	}
}
