// 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"
	"net/url"
	"os"
	"path"
	"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("/", withCacheControl(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 = withLogging(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 cachingStrategy int

const (
	// Disallow browser caching so changes are picked up immediately.
	noCaching cachingStrategy = iota
	// Use an extremely long TTL because cache busting ensures the URL changes
	// when content changes. We achieve this by passing "hash: true" to
	// HtmlWebpackPlugin in frontend/webpack.config.js.
	cacheBusting
)

func getCachingStrategy(url *url.URL) cachingStrategy {
	switch path.Ext(url.Path) {
	case ".js", ".css":
		// Cache busting should put a hash in the query string.
		if url.RawQuery != "" {
			return cacheBusting
		}
	}
	// Default to not caching. In particular, this applies to the "/" request
	// for index.html. We always want to serve that fresh so that new
	// deployments take effect right away.
	return noCaching
}

func withCacheControl(handler http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		switch getCachingStrategy(r.URL) {
		case noCaching:
			w.Header().Add("Cache-Control", "no-cache")
		case cacheBusting:
			// It's traditional to use a TTL of 1 year for cache busting:
			// https://web.dev/uses-long-cache-ttl/
			ttl := 365 * 24 * time.Hour
			w.Header().Add("Cache-Control",
				fmt.Sprintf("max-age=%d, public", int(ttl.Seconds())))
		}
		handler.ServeHTTP(w, r)
	})
}

type statusWriter struct {
	http.ResponseWriter
	status int
}

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

func withLogging(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())
	}
}
