// Copyright 2016 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/hmac"
	"encoding/base64"
	"errors"
	"fmt"
	"net/http"

	"v.io/x/ref/services/allocator"
)

func handleHome(ss *serverState, rs *requestState) error {
	ctx := ss.ctx
	instances, err := serverInstances(ctx, rs.email)
	if err != nil {
		return fmt.Errorf("list error: %v", err)
	}
	type instanceArg struct {
		Instance allocator.Instance
		DestroyURL,
		DebugURL,
		DashboardURL string
	}
	tmplArgs := struct {
		AssetsPrefix,
		ServerName,
		Email,
		CreateURL,
		Message string
		Instances []instanceArg
	}{
		AssetsPrefix: ss.args.staticAssetsPrefix,
		ServerName:   ss.args.serverName,
		Email:        rs.email,
		CreateURL:    makeURL(ctx, routeCreate, params{paramCSRF: rs.csrfToken}),
		Message:      rs.r.FormValue(paramMessage),
	}
	for _, instance := range instances {
		tmplArgs.Instances = append(tmplArgs.Instances, instanceArg{
			Instance:     instance,
			DestroyURL:   makeURL(ctx, routeDestroy, params{paramInstance: instance.Handle, paramCSRF: rs.csrfToken}),
			DashboardURL: makeURL(ctx, routeDashboard, params{paramInstance: instance.Handle}),
			DebugURL: makeURL(
				ctx,
				routeDebug+"/",
				params{
					paramInstance:  instance.Handle,
					paramMountName: instance.MountName,
					paramHMAC:      base64.URLEncoding.EncodeToString(computeHMAC(instance.Handle, instance.MountName))}),
		})
	}
	if err := ss.args.assets.executeTemplate(rs.w, homeTmpl, tmplArgs); err != nil {
		return fmt.Errorf("failed to render home template: %v", err)
	}
	return nil
}

func handleCreate(ss *serverState, rs *requestState) error {
	ctx := ss.ctx
	instance, err := create(ctx, rs.email, ss.args.baseBlessings, ss.args.baseBlessingNames)
	if err != nil {
		return fmt.Errorf("create failed: %v", err)
	}
	redirectTo := makeURL(ctx, routeHome, params{paramMessage: "created " + instance})
	http.Redirect(rs.w, rs.r, redirectTo, http.StatusFound)
	return nil
}

func handleDestroy(ss *serverState, rs *requestState) error {
	ctx := ss.ctx
	instance := rs.r.FormValue(paramInstance)
	if instance == "" {
		return fmt.Errorf("parameter %q required for instance name", paramInstance)
	}
	if err := destroy(ctx, rs.email, instance); err != nil {
		return fmt.Errorf("destroy failed: %v", err)
	}
	redirectTo := makeURL(ctx, routeHome, params{paramMessage: "destroyed " + instance})
	http.Redirect(rs.w, rs.r, redirectTo, http.StatusFound)
	return nil
}

func handleDebug(ss *serverState, rs *requestState, debugBrowserServeMux *http.ServeMux) error {
	instance := rs.r.FormValue(paramInstance)
	if instance == "" {
		return fmt.Errorf("parameter %q required for instance name", paramInstance)
	}
	mountName := rs.r.FormValue(paramMountName)
	if mountName == "" {
		return fmt.Errorf("parameter %q required for instance mount name", paramMountName)
	}
	hmacBase64 := rs.r.FormValue(paramHMAC)
	if hmacBase64 == "" {
		return fmt.Errorf("parameter %q required for name signature", paramHMAC)
	}
	hmacSignature, err := base64.URLEncoding.DecodeString(hmacBase64)
	if err != nil {
		return fmt.Errorf("invalid signature: %v", err)
	}
	if !hmac.Equal(hmacSignature, computeHMAC(instance, mountName)) {
		return errors.New("mismatching signature")
	}
	if err := checkOwner(ss.ctx, rs.email, instance); err != nil {
		return err
	}
	http.StripPrefix(routeDebug, debugBrowserServeMux).ServeHTTP(rs.w, rs.r)
	return nil
}
