// Copyright 2020 The Go 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"
	"html/template"
	"io"
	"log"
	"mime"
	"net/http"
	"os"
	"path"
	"path/filepath"

	"cloud.google.com/go/pubsub"
	"github.com/golang/protobuf/proto"
	"github.com/google/uuid"
	reluipb "golang.org/x/build/cmd/relui/protos"
)

// fileServerHandler returns a http.Handler rooted at root. It will call the next handler provided for requests to "/".
//
// The returned handler sets the appropriate Content-Type and Cache-Control headers for the returned file.
func fileServerHandler(root string, next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Path == "/" {
			next.ServeHTTP(w, r)
			return
		}
		// http.FileServer would correctly return a 404, but we need to check that the file exists
		// before calculating the Content-Type header.
		if _, err := os.Stat(path.Join(root, r.URL.Path)); os.IsNotExist(err) {
			http.NotFound(w, r)
			return
		}
		w.Header().Set("Content-Type", mime.TypeByExtension(path.Ext(r.URL.Path)))
		w.Header().Set("Cache-Control", "no-cache, private, max-age=0")

		fs := http.FileServer(http.Dir(root))
		fs.ServeHTTP(w, r)
	})
}

var (
	homeTmpl        = template.Must(template.Must(layoutTmpl.Clone()).ParseFiles(relativeFile("templates/home.html")))
	layoutTmpl      = template.Must(template.ParseFiles(relativeFile("templates/layout.html")))
	newWorkflowTmpl = template.Must(template.Must(layoutTmpl.Clone()).ParseFiles(relativeFile("templates/new_workflow.html")))
)

// server implements the http handlers for relui.
type server struct {
	// configs are all configured release workflows.
	configs []*reluipb.Workflow

	// store is for persisting application state.
	store store

	// topic is for communicating with relui workers.
	topic *pubsub.Topic
}

type homeResponse struct {
	Workflows []*reluipb.Workflow
}

// homeHandler renders the homepage.
func (s *server) homeHandler(w http.ResponseWriter, _ *http.Request) {
	out := bytes.Buffer{}
	if err := homeTmpl.Execute(&out, homeResponse{Workflows: s.store.Workflows()}); err != nil {
		log.Printf("homeHandler: %v", err)
		http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		return
	}
	io.Copy(w, &out)
}

// newWorkflowHandler presents a form for creating a new workflow.
func (s *server) newWorkflowHandler(w http.ResponseWriter, _ *http.Request) {
	out := bytes.Buffer{}
	if err := newWorkflowTmpl.Execute(&out, nil); err != nil {
		log.Printf("newWorkflowHandler: %v", err)
		http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		return
	}
	io.Copy(w, &out)
}

// createWorkflowHandler persists a new workflow in the datastore.
func (s *server) createWorkflowHandler(w http.ResponseWriter, r *http.Request) {
	if err := r.ParseForm(); err != nil {
		http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
		return
	}
	ref := r.Form.Get("workflow.revision")
	if ref == "" {
		// TODO(golang.org/issue/40279) - render a better error in the form.
		http.Error(w, "workflow revision is required", http.StatusBadRequest)
		return
	}
	if len(s.configs) == 0 {
		http.Error(w, "Unable to create workflow: no workflows configured", http.StatusInternalServerError)
		return
	}
	// Always create the first workflow for now, until we have more.
	wf := proto.Clone(s.configs[0]).(*reluipb.Workflow)
	wf.Id = uuid.New().String()
	for _, t := range wf.GetBuildableTasks() {
		t.Id = uuid.New().String()
	}
	wf.GitSource = &reluipb.GitSource{Ref: ref}
	if err := s.store.AddWorkflow(wf); err != nil {
		log.Printf("Error adding workflow: s.store.AddWorkflow(%v) = %v", wf, err)
		http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		return
	}
	http.Redirect(w, r, "/", http.StatusSeeOther)
}

func (s *server) startTaskHandler(w http.ResponseWriter, r *http.Request) {
	wf := s.store.Workflow(r.PostFormValue("workflow.id"))
	bt := s.store.BuildableTask(r.PostFormValue("workflow.id"), r.PostFormValue("task.id"))
	if bt == nil {
		http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
		return
	}
	res := s.topic.Publish(r.Context(), &pubsub.Message{
		Data: []byte((&reluipb.StartBuildableTaskRequest{
			WorkflowId:        wf.GetId(),
			BuildableTaskId:   bt.GetId(),
			BuildableTaskType: bt.GetTaskType(),
		}).String()),
	})
	if _, err := res.Get(r.Context()); err != nil {
		log.Printf("Error publishing task start: %v", err)
		http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		return
	}
	http.Redirect(w, r, "/", http.StatusSeeOther)
}

// relativeFile returns the path to the provided file or directory,
// conditionally prepending a relative path depending on the environment.
//
// In tests the current directory is ".", but the command may be running from the module root.
func relativeFile(base string) string {
	// Check to see if it is in "." first.
	if _, err := os.Stat(base); err == nil {
		return base
	}
	return filepath.Join("cmd/relui", base)
}
