// 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 (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"path/filepath"
	"strings"
	"text/template"

	"v.io/jiri"
	"v.io/x/lib/cmdline"
)

var (
	portFlag int
)

const (
	defaultRefreshMs = "5000"
)

var tmpl = template.Must(template.New("screenshot").Parse(`
<!DOCTYPE html>
<html>
	<head>
	<style>
	body {
		margin: 0px !important;
		overflow: hidden;
	}
	img {
		width: 100%;
		height: 100%;
	}
	</style>
	<script>
		function loadScreenshot() {
			var xhr = new XMLHttpRequest();
			xhr.onreadystatechange=function() {
				if (xhr.readyState == 4 && xhr.status == 200) {
					var data = JSON.parse(xhr.responseText);
					var ele = document.getElementById('screenshot');
					if (ele) {
						ele.src = 'data:image/png;base64,' + data.Data;
					}
				}
			}
			xhr.open("GET", "/data?n={{ .ScreenshotName }}", true);
			xhr.send();
		}

		function pageLoaded() {
			loadScreenshot();
			setInterval(loadScreenshot, {{ .RefreshMs }});
		}
	</script>
	</head>
	<body onload="pageLoaded()">
	<img id="screenshot"></img>
	</body>
</html>
`))

func init() {
	cmdServe.Flags.IntVar(&portFlag, "port", 8000, "Port for the server.")
}

// cmdServe represents the 'serve' command of the vkiosk tool.
var cmdServe = &cmdline.Command{
	Name:   "serve",
	Short:  "Serve screenshots from local file system or Google Storage",
	Long:   "Serve screenshots from local file system or Google Storage.",
	Runner: cmdline.RunnerFunc(runServe),
}

func runServe(env *cmdline.Env, _ []string) (e error) {
	jirix, err := jiri.NewX(env)
	if err != nil {
		return err
	}
	// Start server.
	http.HandleFunc("/data", func(w http.ResponseWriter, r *http.Request) {
		dataHandler(jirix, w, r)
	})
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		indexHandler(jirix, w, r)
	})
	if err := http.ListenAndServe(fmt.Sprintf(":%d", portFlag), nil); err != nil {
		return fmt.Errorf("ListenAndServe(%d) failed: %v", portFlag, err)
	}

	return nil
}

// indexHandler handles requests for index.html.
func indexHandler(jirix *jiri.X, w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	// Parameter "n" specifies the name of the screenshot file.
	name := r.Form.Get("n")
	if name == "" {
		respondWithError(jirix, fmt.Errorf("parameter 'n' not found"), w)
		return
	}
	// Parameter "r" specifies the refresh interval.
	refreshMs := r.Form.Get("r")
	if refreshMs == "" {
		refreshMs = defaultRefreshMs
	}
	data := struct {
		ScreenshotName string
		RefreshMs      string
	}{
		ScreenshotName: name,
		RefreshMs:      refreshMs,
	}
	if err := tmpl.Execute(w, data); err != nil {
		respondWithError(jirix, fmt.Errorf("Execute() failed: %v", err), w)
		return
	}
}

// dataHandler handles requests for /data.
// It reads screenshots from local file system or Google Storage, and returns
// base64 encoded string as JSON.
func dataHandler(jirix *jiri.X, w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	name := r.Form.Get("n")
	if name == "" {
		respondWithError(jirix, fmt.Errorf("parameter 'n' not found"), w)
		return
	}
	bytes, err := readScreenshot(jirix, name)
	if err != nil {
		respondWithError(jirix, fmt.Errorf("%v", err), w)
		return
	}
	encoded := base64.StdEncoding.EncodeToString(bytes)
	jsonData := struct{ Data string }{
		Data: encoded,
	}
	bytes, err = json.Marshal(&jsonData)
	if err != nil {
		respondWithError(jirix, fmt.Errorf("Marshal() failed: %v", err), w)
		return
	}
	w.Header().Set("Content-Type", "application/json")
	w.Write(bytes)
}

func readScreenshot(jirix *jiri.X, name string) ([]byte, error) {
	if strings.HasPrefix(exportDirFlag, "gs://") {
		args := []string{
			"-q",
			"cat",
			exportDirFlag + "/" + name,
		}
		var output bytes.Buffer
		if err := jirix.NewSeq().Capture(&output, &output).Last("gsutil", args...); err != nil {
			return nil, err
		}
		return output.Bytes(), nil
	}
	return ioutil.ReadFile(filepath.Join(exportDirFlag, name))
}

func respondWithError(jirix *jiri.X, err error, w http.ResponseWriter) {
	fmt.Fprintf(jirix.Stderr(), "%v\n", err)
	http.Error(w, "500 internal server error", http.StatusInternalServerError)
}
