// Copyright 2019 Drone.IO Inc. All rights reserved.
// Use of this source code is governed by the Drone Non-Commercial License
// that can be found in the LICENSE file.

// +build !oss

package builds

import (
	"net/http"
	"strconv"

	"github.com/drone/drone/core"
	"github.com/drone/drone/handler/api/render"
	"github.com/drone/drone/handler/api/request"

	"github.com/go-chi/chi"
)

// HandlePromote returns an http.HandlerFunc that processes http
// requests to promote and re-execute a build.
func HandlePromote(
	repos core.RepositoryStore,
	builds core.BuildStore,
	triggerer core.Triggerer,
) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		var (
			environ   = r.FormValue("target")
			namespace = chi.URLParam(r, "owner")
			name      = chi.URLParam(r, "name")
			user, _   = request.UserFrom(r.Context())
		)
		number, err := strconv.ParseInt(chi.URLParam(r, "number"), 10, 64)
		if err != nil {
			render.BadRequest(w, err)
			return
		}
		repo, err := repos.FindName(r.Context(), namespace, name)
		if err != nil {
			render.NotFound(w, err)
			return
		}
		prev, err := builds.FindNumber(r.Context(), repo.ID, number)
		if err != nil {
			render.NotFound(w, err)
			return
		}
		if environ == "" {
			render.BadRequestf(w, "Missing target environment")
			return
		}

		hook := &core.Hook{
			Parent:       prev.Number,
			Trigger:      user.Login,
			Event:        core.EventPromote,
			Action:       prev.Action,
			Link:         prev.Link,
			Timestamp:    prev.Timestamp,
			Title:        prev.Title,
			Message:      prev.Message,
			Before:       prev.Before,
			After:        prev.After,
			Ref:          prev.Ref,
			Fork:         prev.Fork,
			Source:       prev.Source,
			Target:       prev.Target,
			Author:       prev.Author,
			AuthorName:   prev.AuthorName,
			AuthorEmail:  prev.AuthorEmail,
			AuthorAvatar: prev.AuthorAvatar,
			Deployment:   environ,
			Cron:         prev.Cron,
			Sender:       prev.Sender,
			Params:       map[string]string{},
		}

		for k, v := range prev.Params {
			hook.Params[k] = v
		}

		for key, value := range r.URL.Query() {
			if key == "access_token" {
				continue
			}
			if key == "target" {
				continue
			}
			if len(value) == 0 {
				continue
			}
			hook.Params[key] = value[0]
		}

		result, err := triggerer.Trigger(r.Context(), repo, hook)
		if err != nil {
			render.InternalError(w, err)
		} else {
			render.JSON(w, result, 200)
		}
	}
}
