package baseapp

import (
	"encoding/json"
	"flag"
	"fmt"
	"net/http"
	"path/filepath"
	"runtime"
	"time"

	"github.com/gorilla/mux"
	"go.skia.org/infra/go/common"
	"go.skia.org/infra/go/httputils"
	"go.skia.org/infra/go/sklog"
	secure "gopkg.in/unrolled/secure.v1"
)

var (
	Local        = flag.Bool("local", false, "Running locally if true. As opposed to in production.")
	Port         = flag.String("port", ":8000", "HTTP service address (e.g., ':8000')")
	PromPort     = flag.String("prom_port", ":20000", "Metrics service address (e.g., ':10110')")
	ResourcesDir = flag.String("resources_dir", "", "The directory to find templates, JS, and CSS files. If blank the current directory will be used.")
)

const (
	SERVER_READ_TIMEOUT  = 5 * time.Minute
	SERVER_WRITE_TIMEOUT = 5 * time.Minute
)

// Applications that want to use Serve() must conform the App interface.
type App interface {
	// AddHandlers is called by Serve and the receiver must add all handlers
	// to the passed in mux.Router.
	AddHandlers(*mux.Router)

	// AddMiddleware returns a list of mux.Middleware's to add to the router.
	// This is a good place to add auth middleware.
	AddMiddleware() []mux.MiddlewareFunc
}

// Constructor is a function that builds an App instance.
//
// Used as a parameter to Serve.
type Constructor func() (App, error)

// cspReporter takes csp failure reports and turns them into structured log
// entries.
func cspReporter(w http.ResponseWriter, r *http.Request) {
	var body interface{}
	if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
		sklog.Errorf("Failed to decode csp report: %s", err)
		return
	}
	c := struct {
		Type string      `json:"type"`
		Body interface{} `json:"body"`
	}{
		Type: "csp",
		Body: body,
	}
	b, err := json.Marshal(c)
	if err != nil {
		sklog.Errorf("Failed to marshal csp log entry: %s", err)
		return
	}
	fmt.Println(string(b))
	return
}

func securityMiddleware(allowedHosts []string) mux.MiddlewareFunc {
	// Configure Content Security Policy (CSP).
	addScriptSrc := ""
	if *Local {
		// webpack uses eval() in development mode, so allow unsafe-eval when local.
		addScriptSrc = "'unsafe-eval'"
	}
	// This non-local CSP string passes the tests at https://csp-evaluator.withgoogle.com/.
	//
	// See also: https://csp.withgoogle.com/docs/strict-csp.html
	cspString := fmt.Sprintf("base-uri 'none';  img-src 'self' ; object-src 'none' ; style-src 'self' 'unsafe-inline' ; script-src 'strict-dynamic' $NONCE 'unsafe-inline' %s https: http: ; report-uri /cspreport ;", addScriptSrc)

	// Apply CSP and other security minded headers.
	secureMiddleware := secure.New(secure.Options{
		AllowedHosts:          allowedHosts,
		HostsProxyHeaders:     []string{"X-Forwarded-Host"},
		SSLRedirect:           true,
		SSLProxyHeaders:       map[string]string{"X-Forwarded-Proto": "https"},
		STSSeconds:            60 * 60 * 24 * 365,
		STSIncludeSubdomains:  true,
		ContentSecurityPolicy: cspString,
		IsDevelopment:         *Local,
	})

	return secureMiddleware.Handler
}

// Serve builds and runs the App in a secure manner in out kubernetes cluster.
//
// The constructor builds an App instance. Note that we don't pass in an App
// instance directly, because we want the constructor called after the
// common.Init*() functions are called, i.e. after flags are parsed.
//
// The allowedHosts are the list of domains that are allowed to make requests
// to this app. Make sure to include the domain name of the app itself. For
// example; []string{"am.skia.org"}.
//
// See https://csp.withgoogle.com/docs/strict-csp.html for more information on
// Strict CSP in general.
//
// For this to work every script and style tag must have a nonce attribute
// whose value matches the one sent in the Content-Security-Policy: header. You
// can have webpack inject an attribute with a template for the nonce by adding
// the HtmlWebPackInjectAttributesPlugin to your plugins, i.e.
//
//    config.plugins.push(
//      new HtmlWebpackInjectAttributesPlugin({
//        nonce: "{%.nonce%}",
//      }),
//    );
//
// And then include that nonce when expanding any pages:
//
//    if err := srv.templates.ExecuteTemplate(w, "index.html", map[string]string{
//      "nonce": secure.CSPNonce(r.Context()),
//    }); err != nil {
//     sklog.Errorf("Failed to expand template: %s", err)
//   }
//
// Since our audience is small and only uses modern browsers we shouldn't need
// any further XSS protection. For example, even if a user is logged into
// another Google site that is compromised, while they can request the main
// index page and get both the csrf token and value, they couldn't POST it back
// to the site we are serving since that site wouldn't be listed in
// allowedHosts.
//
// CSP failures will be logged as structured log events.
//
// Static resources, e.g. webpack output, will be served at '/static/' and will
// serve the contents of the '/dist' directory.
func Serve(constructor Constructor, allowedHosts []string) {
	// Do common init.
	common.InitWithMust(
		"generic-k8s-app", // The app name is only used by ../go/sklog/cloud_logging, and we don't use that on k8s.
		common.PrometheusOpt(PromPort),
		common.MetricsLoggingOpt(),
	)

	// Fix up flag values.
	if *ResourcesDir == "" {
		_, filename, _, _ := runtime.Caller(1)
		*ResourcesDir = filepath.Join(filepath.Dir(filename), "../../dist")
	}

	// Build App instance.
	app, err := constructor()
	if err != nil {
		sklog.Fatal(err)
	}

	// Add all routing.
	r := mux.NewRouter()
	r.HandleFunc("/cspreport", cspReporter).Methods("POST")
	r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.HandlerFunc(httputils.MakeResourceHandler(*ResourcesDir))))
	app.AddHandlers(r)

	// Layer on all the middleware.
	middleware := []mux.MiddlewareFunc{}
	if !*Local {
		middleware = append(middleware, httputils.HealthzAndHTTPS)
	}
	middleware = append(middleware, app.AddMiddleware()...)
	middleware = append(middleware,
		httputils.LoggingGzipRequestResponse,
		securityMiddleware(allowedHosts),
	)
	r.Use(middleware...)

	// Start serving.
	sklog.Infoln("Ready to serve.")
	server := &http.Server{
		Addr:           *Port,
		Handler:        r,
		ReadTimeout:    SERVER_READ_TIMEOUT,
		WriteTimeout:   SERVER_WRITE_TIMEOUT,
		MaxHeaderBytes: 1 << 20,
	}
	sklog.Fatal(server.ListenAndServe())
}
