package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"

	"code.google.com/p/goauth2/oauth"
)

var (
	assetPath  = "cmd/deploy/assets"
	httpPort   = "8081"
	configFile = "config/dev.json"
	GitCommit  = "development"
)

var config Config

func init() {
	if os.Getenv("ASSET_PATH") != "" {
		assetPath = os.Getenv("ASSET_PATH")
	}
	if os.Getenv("HTTP_PORT") != "" {
		httpPort = os.Getenv("HTTP_PORT")
	}
	if os.Getenv("CONFIG") != "" {
		configFile = os.Getenv("CONFIG")
	}
}

func main() {
	file, err := ioutil.ReadFile(configFile)
	if err != nil {
		log.Fatalf("error reading config file: %v", err)
	}
	json.Unmarshal(file, &config)
	oauthConfig.ClientId = config.GithubClientId
	oauthConfig.ClientSecret = config.GithubClientSecret

	http.HandleFunc("/running", healthCheck)
	http.HandleFunc("/authorize", handleAuthorize)
	http.HandleFunc("/github_oauth_callback", handleGithubOauth)
	http.HandleFunc("/config", handleConfig)
	http.Handle("/", http.FileServer(http.Dir(assetPath)))
	log.Printf("Listening on port %v...", httpPort)
	http.ListenAndServe(":"+httpPort, nil)
}

type Config struct {
	GithubClientId     string `json:"github_client_id"`
	GithubClientSecret string `json:"github_client_secret"`
	SkadiHost string `json:"skadi_host"`
}

var oauthConfig = &oauth.Config{
	AuthURL:  "https://git-aws.internal.justin.tv/login/oauth/authorize",
	TokenURL: "https://git-aws.internal.justin.tv/login/oauth/access_token",
	Scope:    "repo,admin:org",
}

func handleAuthorize(w http.ResponseWriter, r *http.Request) {
	http.Redirect(w, r, oauthConfig.AuthCodeURL(""), http.StatusFound)
}

func handleGithubOauth(w http.ResponseWriter, r *http.Request) {
	code := r.FormValue("code")

	transport := &oauth.Transport{Config: oauthConfig}

	token, err := transport.Exchange(code)
	if err != nil {
		log.Println("Exchange:", err)
		w.WriteHeader(http.StatusInternalServerError)
		fmt.Fprintf(w, "Error: %v", err)
		return
	}

	// putting token in the cookie is not smart, but ok until we introduce a database
	cookie := &http.Cookie{Name: "GithubAccessToken", Value: token.AccessToken}
	http.SetCookie(w, cookie)

	http.Redirect(w, r, "/", http.StatusFound)
}

func healthCheck(w http.ResponseWriter, req *http.Request) {
	type hcStruct struct {
		GitCommit string
	}

	if err := json.NewEncoder(w).Encode(&hcStruct{
		GitCommit: GitCommit,
	}); err != nil {
		log.Printf("Error encoding healthCheck: %v", err)
	}
}

func handleConfig(w http.ResponseWriter, r *http.Request) {
	type configStruct struct {
		SkadiHost string `json:"skadi_host"`
	}

	json.NewEncoder(w).Encode(&configStruct{
		SkadiHost: config.SkadiHost,
	})
}
