package backend

import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"time"

	"github.com/restic/restic/internal/debug"
)

// Transport returns a new http.RoundTripper with default settings applied. If
// a custom rootCertFilename is non-empty, it must point to a valid PEM file,
// otherwise the function will return an error.
func Transport(rootCertFilenames []string) (http.RoundTripper, error) {
	// copied from net/http
	tr := &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		DialContext: (&net.Dialer{
			Timeout:   30 * time.Second,
			KeepAlive: 30 * time.Second,
			DualStack: true,
		}).DialContext,
		MaxIdleConns:          100,
		MaxIdleConnsPerHost:   100,
		IdleConnTimeout:       90 * time.Second,
		TLSHandshakeTimeout:   10 * time.Second,
		ExpectContinueTimeout: 1 * time.Second,
	}

	if rootCertFilenames == nil {
		return debug.RoundTripper(tr), nil
	}

	p := x509.NewCertPool()
	for _, filename := range rootCertFilenames {
		if filename == "" {
			return nil, fmt.Errorf("empty filename for root certificate supplied")
		}
		b, err := ioutil.ReadFile(filename)
		if err != nil {
			return nil, fmt.Errorf("unable to read root certificate: %v", err)
		}
		if ok := p.AppendCertsFromPEM(b); !ok {
			return nil, fmt.Errorf("cannot parse root certificate from %q", filename)
		}
	}

	tr.TLSClientConfig = &tls.Config{
		RootCAs: p,
	}

	// wrap in the debug round tripper
	return debug.RoundTripper(tr), nil
}