// Copyright 2015 The Vanadium 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 main

import (
	"crypto/rand"
	"encoding/base64"
	"fmt"
	"html/template"
	"net"
	"net/http"
	"net/url"
	"os"
	"os/exec"
	"strings"
	"time"

	"v.io/v23/context"
	"v.io/v23/options"
	"v.io/v23/security"
	"v.io/x/lib/vlog"
	"v.io/x/ref/services/identity"
)

func exchangeMacaroonForBlessing(ctx *context.T, macaroonChan <-chan string) (security.Blessings, error) {
	service, macaroon, serviceKey, err := prepareBlessArgs(ctx, macaroonChan)
	if err != nil {
		return security.Blessings{}, err
	}

	ctx, cancel := context.WithTimeout(ctx, time.Minute)
	defer cancel()

	// Authorize the server by its public key (obtained from macaroonChan).
	// Must skip authorization during name resolution because the identity
	// service is not a trusted root yet.
	blessings, err := identity.MacaroonBlesserClient(service).Bless(ctx, macaroon, options.SkipServerEndpointAuthorization{}, options.ServerPublicKey{
		PublicKey: serviceKey,
	})
	if err != nil {
		return security.Blessings{}, fmt.Errorf("failed to get blessing from %q: %v", service, err)
	}
	return blessings, nil
}

func prepareBlessArgs(ctx *context.T, macaroonChan <-chan string) (service, macaroon string, root security.PublicKey, err error) {
	macaroon = <-macaroonChan
	service = <-macaroonChan

	marshalKey, err := base64.URLEncoding.DecodeString(<-macaroonChan)
	if err != nil {
		return "", "", nil, fmt.Errorf("failed to decode root key: %v", err)
	}
	root, err = security.UnmarshalPublicKey(marshalKey)
	if err != nil {
		return "", "", nil, fmt.Errorf("failed to unmarshal root key: %v", err)
	}

	return service, macaroon, root, nil
}

func getMacaroonForBlessRPC(key security.PublicKey, blessServerURL string, blessedChan <-chan string, browser bool) (<-chan string, error) {
	// Setup a HTTP server to recieve a blessing macaroon from the identity server.
	// Steps:
	// 1. Generate a state token to be included in the HTTP request
	//    (though, arguably, the random port assigment for the HTTP server is enough
	//    for XSRF protection)
	// 2. Setup a HTTP server which will receive the final blessing macaroon from the id server.
	// 3. Print out the link (to start the auth flow) for the user to click.
	// 4. Return the macaroon and the rpc object name(where to make the MacaroonBlesser.Bless RPC call)
	//    in the "result" channel.
	var stateBuf [32]byte
	if _, err := rand.Read(stateBuf[:]); err != nil {
		return nil, fmt.Errorf("failed to generate state token for OAuth: %v", err)
	}
	state := base64.URLEncoding.EncodeToString(stateBuf[:])

	ln, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		return nil, fmt.Errorf("failed to setup authorization code interception server: %v", err)
	}
	result := make(chan string)

	redirectURL := fmt.Sprintf("http://%s/macaroon", ln.Addr())
	http.HandleFunc("/macaroon", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "text/html")
		tmplArgs := struct {
			Blessings string
			ErrShort  string
			ErrLong   string
			Browser   bool
		}{
			Browser: browser,
		}
		defer func() {
			if len(tmplArgs.ErrShort) > 0 {
				w.WriteHeader(http.StatusBadRequest)
			}
			if err := tmpl.Execute(w, tmplArgs); err != nil {
				vlog.Info("Failed to render template:", err)
			}
		}()

		defer close(result)
		if r.FormValue("state") != state {
			tmplArgs.ErrShort = "Unexpected request"
			tmplArgs.ErrLong = "Mismatched state parameter. Possible cross-site-request-forgery?"
			return
		}
		if errEnc := r.FormValue("error"); errEnc != "" {
			tmplArgs.ErrShort = "Failed to get blessings"
			errBytes, err := base64.URLEncoding.DecodeString(errEnc)
			if err != nil {
				tmplArgs.ErrLong = err.Error()
			} else {
				tmplArgs.ErrLong = string(errBytes)
			}
			return
		}
		result <- r.FormValue("macaroon")
		result <- r.FormValue("object_name")
		result <- r.FormValue("root_key")
		blessed, ok := <-blessedChan
		if !ok {
			tmplArgs.ErrShort = "No blessings received"
			tmplArgs.ErrLong = "Unable to obtain blessings from the Vanadium service"
			return
		}
		tmplArgs.Blessings = blessed
		ln.Close()
	})
	go http.Serve(ln, nil)

	// Print the link to start the flow.
	url, err := seekBlessingsURL(key, blessServerURL, redirectURL, state)
	if err != nil {
		return nil, fmt.Errorf("failed to create seekBlessingsURL: %s", err)
	}
	fmt.Fprintln(os.Stdout, "Please visit the following URL to seek blessings:")
	fmt.Fprintln(os.Stdout, url)
	// Make an attempt to start the browser as a convenience.
	// If it fails, doesn't matter - the client can see the URL printed above.
	// Use exec.Command().Start instead of exec.Command().Run since there is no
	// need to wait for the command to return (and indeed on some window managers,
	// the command will not exit until the browser is closed).
	if len(openCommand) != 0 && browser {
		exec.Command(openCommand, url).Start()
	}
	return result, nil
}

func seekBlessingsURL(key security.PublicKey, blessServerURL, redirectURL, state string) (string, error) {
	baseURL, err := url.Parse(joinURL(blessServerURL, identity.SeekBlessingsRoute))
	if err != nil {
		return "", fmt.Errorf("failed to parse url: %v", err)
	}
	keyBytes, err := key.MarshalBinary()
	if err != nil {
		return "", fmt.Errorf("failed to marshal public key: %v", err)
	}
	params := url.Values{}
	params.Add("redirect_url", redirectURL)
	params.Add("state", state)
	params.Add("public_key", base64.URLEncoding.EncodeToString(keyBytes))
	baseURL.RawQuery = params.Encode()
	return baseURL.String(), nil
}

func joinURL(baseURL, suffix string) string {
	if !strings.HasSuffix(baseURL, "/") {
		baseURL += "/"
	}
	return baseURL + suffix
}

var tmpl = template.Must(template.New("name").Parse(`<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<!--Excluding any third-party hosted resources like scripts and stylesheets because otherwise we run the risk of leaking the macaroon out of this page (e.g., via the referrer header) -->
<title>Vanadium Identity: Google</title>
{{if and .Browser .Blessings}}
<!--Attempt to close the window. Though this script does not work on many browser configurations-->
<script type="text/javascript">window.close();</script>
{{end}}
</head>
<body>
<div>
{{if .ErrShort}}
<center><h1><span style="color:#FF6E40;">Error: </span>{{.ErrShort}}</h1></center>
<center><h2>{{.ErrLong}}</h2></center>
{{else}}
<center><h1>Received blessings: <tt>{{.Blessings}}</tt></h1></center>
<center><h2>You may close this tab now.</h2></center>
{{end}}
</div>
</body>
</html>`))
