<commit_before>package installer

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net"
	"net/http"
	"path/filepath"
	"strings"
	"time"

	"github.com/flynn/flynn/Godeps/_workspace/src/github.com/awslabs/aws-sdk-go/aws"
	"github.com/flynn/flynn/Godeps/_workspace/src/github.com/badgerodon/ioutil"
	"github.com/flynn/flynn/Godeps/_workspace/src/github.com/flynn/oauth2"
	"github.com/flynn/flynn/Godeps/_workspace/src/github.com/julienschmidt/httprouter"
	"github.com/flynn/flynn/Godeps/_workspace/src/github.com/pkg/browser"
	log "github.com/flynn/flynn/Godeps/_workspace/src/gopkg.in/inconshreveable/log15.v2"
	"github.com/flynn/flynn/pkg/azure"
	"github.com/flynn/flynn/pkg/cors"
	"github.com/flynn/flynn/pkg/httphelper"
	"github.com/flynn/flynn/pkg/sse"
)

type assetManifest struct {
	Assets map[string]string `json:"assets"`
}

type htmlTemplateData struct {
	ApplicationJSPath  string
	NormalizeCSSPath   string
	FontAwesomeCSSPath string
	ApplicationCSSPath string
	ReactJSPath        string
}

type installerJSConfig struct {
	Endpoints            map[string]string `json:"endpoints"`
	HasAWSEnvCredentials bool              `json:"has_aws_env_credentials"`
	AWSEnvCredentialsID  string            `json:"aws_env_credentials_id,omitempty"`
}

type httpAPI struct {
	AWSEnvCreds  aws.CredentialsProvider
	Installer    *Installer
	logger       log.Logger
	clientConfig installerJSConfig
}

func ServeHTTP() error {
	logger := log.New()
	installer := NewInstaller(logger)

	api := &httpAPI{
		Installer: installer,
		logger:    logger,
		clientConfig: installerJSConfig{
			Endpoints: map[string]string{
				"clusters":           "/clusters",
				"cluster":            "/clusters/:id",
				"events":             "/events",
				"prompt":             "/clusters/:id/prompts/:prompt_id",
				"credentials":        "/credentials",
				"regions":            "/regions",
				"azureSubscriptions": "/azure/subscriptions",
			},
		},
	}

	if creds, err := aws.EnvCreds(); err == nil {
		api.AWSEnvCreds = creds
		if c, err := creds.Credentials(); err == nil {
			api.clientConfig.HasAWSEnvCredentials = true
			api.clientConfig.AWSEnvCredentialsID = c.AccessKeyID
		}
	}

	httpRouter := httprouter.New()

	httpRouter.GET("/", api.ServeTemplate)
	httpRouter.GET("/credentials", api.ServeTemplate)
	httpRouter.GET("/credentials/:id", api.ServeTemplate)
	httpRouter.GET("/clusters/:id", api.ServeTemplate)
	httpRouter.GET("/clusters/:id/delete", api.ServeTemplate)
	httpRouter.GET("/oauth/azure", api.ServeTemplate)
	httpRouter.DELETE("/clusters/:id", api.DeleteCluster)
	httpRouter.POST("/clusters", api.LaunchCluster)
	httpRouter.GET("/events", api.Events)
	httpRouter.POST("/clusters/:id/prompts/:prompt_id", api.Prompt)
	httpRouter.GET("/assets/*assetPath", api.ServeAsset)
	httpRouter.POST("/credentials", api.NewCredential)
	httpRouter.DELETE("/credentials/:type/:id", api.DeleteCredential)
	httpRouter.GET("/regions", api.GetCloudRegions)
	httpRouter.GET("/azure/subscriptions", api.GetAzureSubscriptions)

	l, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		return err
	}
	addr := fmt.Sprintf("http://localhost:%d", l.Addr().(*net.TCPAddr).Port)
	fmt.Printf("Open %s in your browser to continue.\n", addr)
	browser.OpenURL(addr)
	return http.Serve(l, api.CorsHandler(httpRouter, addr))
}

func (api *httpAPI) CorsHandler(main http.Handler, addr string) http.Handler {
	return (&cors.Options{
		AllowOrigins:     []string{addr},
		AllowMethods:     []string{"GET", "POST"},
		AllowHeaders:     []string{"Authorization", "Accept", "Content-Type", "If-Match", "If-None-Match"},
		ExposeHeaders:    []string{"ETag"},
		AllowCredentials: false,
		MaxAge:           time.Hour,
	}).Handler(main)
}

func (api *httpAPI) Asset(path string) (io.ReadSeeker, error) {
	data, err := Asset(path)
	if err != nil {
		return nil, err
	}
	return bytes.NewReader(data), nil
}

func (api *httpAPI) AssetManifest() (*assetManifest, error) {
	data, err := api.Asset(filepath.Join("app", "build", "manifest.json"))
	if err != nil {
		return nil, err
	}
	dec := json.NewDecoder(data)
	var manifest *assetManifest
	if err := dec.Decode(&manifest); err != nil {
		return nil, err
	}
	return manifest, nil
}

func (api *httpAPI) LaunchCluster(w http.ResponseWriter, req *http.Request, params httprouter.Params) {<commit_msg>installer: Add redirect for /clusters -> /<commit_after>package installer

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net"
	"net/http"
	"path/filepath"
	"strings"
	"time"

	"github.com/flynn/flynn/Godeps/_workspace/src/github.com/awslabs/aws-sdk-go/aws"
	"github.com/flynn/flynn/Godeps/_workspace/src/github.com/badgerodon/ioutil"
	"github.com/flynn/flynn/Godeps/_workspace/src/github.com/flynn/oauth2"
	"github.com/flynn/flynn/Godeps/_workspace/src/github.com/julienschmidt/httprouter"
	"github.com/flynn/flynn/Godeps/_workspace/src/github.com/pkg/browser"
	log "github.com/flynn/flynn/Godeps/_workspace/src/gopkg.in/inconshreveable/log15.v2"
	"github.com/flynn/flynn/pkg/azure"
	"github.com/flynn/flynn/pkg/cors"
	"github.com/flynn/flynn/pkg/httphelper"
	"github.com/flynn/flynn/pkg/sse"
)

type assetManifest struct {
	Assets map[string]string `json:"assets"`
}

type htmlTemplateData struct {
	ApplicationJSPath  string
	NormalizeCSSPath   string
	FontAwesomeCSSPath string
	ApplicationCSSPath string
	ReactJSPath        string
}

type installerJSConfig struct {
	Endpoints            map[string]string `json:"endpoints"`
	HasAWSEnvCredentials bool              `json:"has_aws_env_credentials"`
	AWSEnvCredentialsID  string            `json:"aws_env_credentials_id,omitempty"`
}

type httpAPI struct {
	AWSEnvCreds  aws.CredentialsProvider
	Installer    *Installer
	logger       log.Logger
	clientConfig installerJSConfig
}

func ServeHTTP() error {
	logger := log.New()
	installer := NewInstaller(logger)

	api := &httpAPI{
		Installer: installer,
		logger:    logger,
		clientConfig: installerJSConfig{
			Endpoints: map[string]string{
				"clusters":           "/clusters",
				"cluster":            "/clusters/:id",
				"events":             "/events",
				"prompt":             "/clusters/:id/prompts/:prompt_id",
				"credentials":        "/credentials",
				"regions":            "/regions",
				"azureSubscriptions": "/azure/subscriptions",
			},
		},
	}

	if creds, err := aws.EnvCreds(); err == nil {
		api.AWSEnvCreds = creds
		if c, err := creds.Credentials(); err == nil {
			api.clientConfig.HasAWSEnvCredentials = true
			api.clientConfig.AWSEnvCredentialsID = c.AccessKeyID
		}
	}

	httpRouter := httprouter.New()

	httpRouter.GET("/", api.ServeTemplate)
	httpRouter.GET("/credentials", api.ServeTemplate)
	httpRouter.GET("/credentials/:id", api.ServeTemplate)
	httpRouter.GET("/clusters/:id", api.ServeTemplate)
	httpRouter.GET("/clusters/:id/delete", api.ServeTemplate)
	httpRouter.GET("/oauth/azure", api.ServeTemplate)
	httpRouter.DELETE("/clusters/:id", api.DeleteCluster)
	httpRouter.GET("/clusters", api.RedirectRoot)
	httpRouter.POST("/clusters", api.LaunchCluster)
	httpRouter.GET("/events", api.Events)
	httpRouter.POST("/clusters/:id/prompts/:prompt_id", api.Prompt)
	httpRouter.GET("/assets/*assetPath", api.ServeAsset)
	httpRouter.POST("/credentials", api.NewCredential)
	httpRouter.DELETE("/credentials/:type/:id", api.DeleteCredential)
	httpRouter.GET("/regions", api.GetCloudRegions)
	httpRouter.GET("/azure/subscriptions", api.GetAzureSubscriptions)

	l, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		return err
	}
	addr := fmt.Sprintf("http://localhost:%d", l.Addr().(*net.TCPAddr).Port)
	fmt.Printf("Open %s in your browser to continue.\n", addr)
	browser.OpenURL(addr)
	return http.Serve(l, api.CorsHandler(httpRouter, addr))
}

func (api *httpAPI) CorsHandler(main http.Handler, addr string) http.Handler {
	return (&cors.Options{
		AllowOrigins:     []string{addr},
		AllowMethods:     []string{"GET", "POST"},
		AllowHeaders:     []string{"Authorization", "Accept", "Content-Type", "If-Match", "If-None-Match"},
		ExposeHeaders:    []string{"ETag"},
		AllowCredentials: false,
		MaxAge:           time.Hour,
	}).Handler(main)
}

func (api *httpAPI) Asset(path string) (io.ReadSeeker, error) {
	data, err := Asset(path)
	if err != nil {
		return nil, err
	}
	return bytes.NewReader(data), nil
}

func (api *httpAPI) AssetManifest() (*assetManifest, error) {
	data, err := api.Asset(filepath.Join("app", "build", "manifest.json"))
	if err != nil {
		return nil, err
	}
	dec := json.NewDecoder(data)
	var manifest *assetManifest
	if err := dec.Decode(&manifest); err != nil {
		return nil, err
	}
	return manifest, nil
}

func (api *httpAPI) RedirectRoot(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
	http.Redirect(w, req, "/", 302)
}

func (api *httpAPI) LaunchCluster(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
{'fraction_non_alphanumeric': 0.15272274425450016, 'fraction_numerical': 0.0028302954828484093, 'mean_word_length': 4.196470588235294, 'pattern_counts': {'":': 14, '<': 3, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2593835', 'n_tokens_mistral': 3233, 'n_tokens_neox': 3122, 'n_words': 539}