// Copyright 2017 The Go 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"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"strings"
	"time"

	"golang.org/x/tools/godoc/static"
)

type server struct {
	mux      *http.ServeMux
	db       store
	log      logger
	cache    responseCache
	gotip    bool // if set, server is using gotip
	examples *examplesHandler

	// When the executable was last modified. Used for caching headers of compiled assets.
	modtime time.Time
}

func newServer(options ...func(s *server) error) (*server, error) {
	s := &server{mux: http.NewServeMux()}
	for _, o := range options {
		if err := o(s); err != nil {
			return nil, err
		}
	}
	if s.db == nil {
		return nil, fmt.Errorf("must provide an option func that specifies a datastore")
	}
	if s.log == nil {
		return nil, fmt.Errorf("must provide an option func that specifies a logger")
	}
	if s.examples == nil {
		return nil, fmt.Errorf("must provide an option func that sets the examples handler")
	}
	s.init()
	return s, nil
}

func (s *server) init() {
	s.mux.HandleFunc("/", s.handleEdit)
	s.mux.HandleFunc("/fmt", s.handleFmt)
	s.mux.HandleFunc("/version", s.handleVersion)
	s.mux.HandleFunc("/vet", s.commandHandler("vet", vetCheck))
	s.mux.HandleFunc("/compile", s.commandHandler("prog", compileAndRun))
	s.mux.HandleFunc("/share", s.handleShare)
	s.mux.HandleFunc("/playground.js", s.handlePlaygroundJS)
	s.mux.HandleFunc("/favicon.ico", handleFavicon)
	s.mux.HandleFunc("/_ah/health", s.handleHealthCheck)

	staticHandler := http.StripPrefix("/static/", http.FileServer(http.Dir("./static")))
	s.mux.Handle("/static/", staticHandler)
	s.mux.Handle("/doc/play/", http.StripPrefix("/doc/play/", s.examples))
}

func (s *server) handlePlaygroundJS(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-type", "text/javascript; charset=utf-8")
	rd := strings.NewReader(static.Files["playground.js"])
	http.ServeContent(w, r, "playground.js", s.modtime, rd)
}

func handleFavicon(w http.ResponseWriter, r *http.Request) {
	http.ServeFile(w, r, "./static/favicon.ico")
}

func (s *server) handleHealthCheck(w http.ResponseWriter, r *http.Request) {
	if err := s.healthCheck(r.Context()); err != nil {
		http.Error(w, "Health check failed: "+err.Error(), http.StatusInternalServerError)
		return
	}
	fmt.Fprint(w, "ok")
}

func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if r.Header.Get("X-Forwarded-Proto") == "http" {
		r.URL.Scheme = "https"
		r.URL.Host = r.Host
		http.Redirect(w, r, r.URL.String(), http.StatusFound)
		return
	}
	if r.Header.Get("X-Forwarded-Proto") == "https" {
		w.Header().Set("Strict-Transport-Security", "max-age=31536000; preload")
	}
	s.mux.ServeHTTP(w, r)
}

// writeJSONResponse JSON-encodes resp and writes to w with the given HTTP
// status.
func (s *server) writeJSONResponse(w http.ResponseWriter, resp interface{}, status int) {
	w.Header().Set("Content-Type", "application/json")
	var buf bytes.Buffer
	if err := json.NewEncoder(&buf).Encode(resp); err != nil {
		s.log.Errorf("error encoding response: %v", err)
		http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		return
	}
	w.WriteHeader(status)
	if _, err := io.Copy(w, &buf); err != nil {
		s.log.Errorf("io.Copy(w, &buf): %v", err)
		return
	}
}
