// 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.

// Handlers for HTTP requests to save and load playground examples.
//
// handlerSave() handles a POST request with bundled playground source code.
// The bundle is persisted in a database and a unique ID returned.
// handlerLoad() handles a GET request with an id parameter. It returns the
// bundle saved under the provided ID, if any.
// The current implementation uses a MySQL-like SQL database for persistence.

package main

import (
	"encoding/json"
	"fmt"
	"net/http"

	"v.io/x/playground/compilerd/storage"
	"v.io/x/playground/lib/log"
)

//////////////////////////////////////////
// HTTP request handlers

// GET request that returns the saved bundle for the given id.
func handlerLoad(w http.ResponseWriter, r *http.Request) {
	if !handleCORS(w, r) {
		return
	}

	// Check method and read GET parameters.
	if !checkGetMethod(w, r) {
		return
	}
	bId := r.FormValue("id")
	if bId == "" {
		storageError(w, http.StatusBadRequest, "Must specify id to load.")
		return
	}
	bData, err := storage.GetBundleDataByLinkId(bId)
	if err == storage.ErrNotFound {
		storageError(w, http.StatusNotFound, "No data found for provided id.")
		return
	} else if err != nil {
		storageInternalError(w, "Error getting bundleLink for id", bId, ":", err)
		return
	}

	storageRespond(w, http.StatusOK, &StorageResponse{
		Link: bId,
		Data: bData.Json,
	})
	return
}

// POST request that saves the body as a new bundle and returns the bundle id.
func handlerSave(w http.ResponseWriter, r *http.Request) {
	if !handleCORS(w, r) {
		return
	}

	// Check method and read POST body.
	// Limit is set to maxSize+1 to allow distinguishing between exactly maxSize
	// and larger than maxSize requests.
	requestBody := getPostBody(w, r, *maxSize+1)
	if requestBody == nil {
		return
	}
	if len(requestBody) > *maxSize {
		storageError(w, http.StatusBadRequest, "Program too large.")
		return
	}

	// TODO(ivanpi): Check if bundle is parseable. Format/lint?

	bLink, bData, err := storage.StoreBundleLinkAndData(requestBody)
	if err != nil {
		storageInternalError(w, err)
		return
	}

	storageRespond(w, http.StatusOK, &StorageResponse{
		Link: bLink.Id,
		Data: bData.Json,
	})
}

//////////////////////////////////////////
// Response handling

type StorageResponse struct {
	// Error message. If empty, request was successful.
	Error string
	// Bundle ID for the saved/loaded bundle.
	Link string
	// Contents of the loaded bundle.
	Data string
}

// Sends response to client. Request handler should exit after this call.
func storageRespond(w http.ResponseWriter, status int, body *StorageResponse) {
	bodyJson, _ := json.Marshal(body)
	w.Header().Add("Content-Type", "application/json")
	w.Header().Add("Content-Length", fmt.Sprintf("%d", len(bodyJson)))
	w.WriteHeader(status)
	w.Write(bodyJson)
}

// Sends error response with specified message to client.
func storageError(w http.ResponseWriter, status int, msg string) {
	storageRespond(w, status, &StorageResponse{
		Error: msg,
	})
}

// Logs error internally and sends non-specific error response to client.
func storageInternalError(w http.ResponseWriter, v ...interface{}) {
	if len(v) > 0 {
		log.Errorln(v...)
	}
	storageError(w, http.StatusInternalServerError, "Internal error, please retry.")
}
