// 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 https contains helpers for starting an HTTPS server.
package https // import "golang.org/x/build/internal/https"

import (
	"context"
	"crypto/tls"
	"fmt"
	"net"
	"net/http"
	"strings"
	"time"

	"cloud.google.com/go/storage"
	"golang.org/x/build/autocertcache"
	"golang.org/x/crypto/acme/autocert"
	"golang.org/x/net/http2"
)

// Options are the configuration parameters for the HTTP(S) server.
type Options struct {
	// Addr specifies the host and port the server should listen on.
	Addr string

	// AutocertCacheBucket specifies the name of the GCS bucket for
	// Let’s Encrypt to use. If this is not specified, then HTTP traffic is
	// served on Addr.
	AutocertCacheBucket string
}

var defaultOptions = &Options{
	Addr: "localhost:6343",
}

// ListenAndServe serves the given handler by HTTPS (and HTTP, redirecting to
// HTTPS) using the provided options.
//
// ListenAndServe always returns a non-nil error.
func ListenAndServe(handler http.Handler, opt *Options) error {
	if opt == nil {
		opt = defaultOptions
	}
	ln, err := net.Listen("tcp", opt.Addr)
	if err != nil {
		return fmt.Errorf(`net.Listen("tcp", %q): %v`, opt.Addr, err)
	}
	defer ln.Close()

	if opt.AutocertCacheBucket == "" {
		err := http.Serve(ln, handler)
		return fmt.Errorf("http.Serve = %v", err)
	}

	// handler is served primarily via HTTPS, so just redirect HTTP to HTTPS.
	redirect := &http.Server{
		Handler: http.HandlerFunc(redirectToHTTPS),
	}
	errc := make(chan error)
	go func() {
		err := redirect.Serve(ln)
		errc <- fmt.Errorf("http.Serve = %v", err)
	}()

	ctx, cancel := context.WithCancel(context.TODO())
	go func() {
		errc <- serveAutocertTLS(ctx, handler, opt.AutocertCacheBucket)
	}()

	// Wait for the first error.
	err = <-errc

	// Stop the other handler (whichever it may be) and wait for it to return.
	redirect.Close()
	cancel()
	<-errc

	return err
}

// redirectToHTTPS will redirect to the https version of the URL requested. If
// r.TLS is set or r.Host is empty, a 404 not found response is sent.
func redirectToHTTPS(w http.ResponseWriter, r *http.Request) {
	if r.TLS != nil || r.Host == "" {
		http.NotFound(w, r)
		return
	}

	http.Redirect(w, r, "https://"+r.Host+r.RequestURI, http.StatusFound)
}

// serveAutocertTLS serves the handler h on port 443 using the given GCS bucket
// for its autocert cache. It will only serve on domains of the form *.golang.org.
//
// serveAutocertTLS always returns a non-nil error.
func serveAutocertTLS(ctx context.Context, h http.Handler, bucket string) error {
	ln, err := net.Listen("tcp", ":443")
	if err != nil {
		return err
	}
	defer ln.Close()

	ctx, cancel := context.WithCancel(ctx)
	server := &http.Server{Handler: h}
	done := make(chan struct{})
	go func() {
		<-ctx.Done()
		server.Close()
		close(done)
	}()
	defer func() {
		cancel()
		<-done
	}()

	sc, err := storage.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("storage.NewClient: %v", err)
	}
	const hostSuffix = ".golang.org"
	m := autocert.Manager{
		Prompt: autocert.AcceptTOS,
		HostPolicy: func(ctx context.Context, host string) error {
			if !strings.HasSuffix(host, hostSuffix) {
				return fmt.Errorf("refusing to serve autocert on provided domain (%q), must have the suffix %q",
					host, hostSuffix)
			}
			return nil
		},
		Cache: autocertcache.NewGoogleCloudStorageCache(sc, bucket),
	}
	tlsLn := tls.NewListener(tcpKeepAliveListener{ln.(*net.TCPListener)}, m.TLSConfig())
	if err := http2.ConfigureServer(server, nil); err != nil {
		return fmt.Errorf("http2.ConfigureServer: %v", err)
	}
	return server.Serve(tlsLn)
}

type tcpKeepAliveListener struct {
	*net.TCPListener
}

func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) {
	tc, err := ln.AcceptTCP()
	if err != nil {
		return
	}
	tc.SetKeepAlive(true)
	tc.SetKeepAlivePeriod(3 * time.Minute)
	return tc, nil
}
