//
//  tank, Import and Playlist Daemon for Aura project
//  Copyright (C) 2017-2020 Christian Pointner <equinox@helsinki.at>
//
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Affero General Public License as
//  published by the Free Software Foundation, either version 3 of the
//  License, or (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU Affero General Public License for more details.
//
//  You should have received a copy of the GNU Affero General Public License
//  along with this program.  If not, see <https://www.gnu.org/licenses/>.
//

package v1

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

// ListImportsOfShow returns a list of all running and pending imports for files belonging to this show.
// @Summary      List imports
// @Description  Lists all running and pending imports
// @Produce      json
// @Param        name    path      string  true   "Name of the show"
// @Param        limit   query     int     false  "Limit number of results"
// @Param        offset  query     int     false  "Start listing from offset"
// @Success      200     {object}  JobsListing
// @Failure      400     {object}  ErrorResponse
// @Failure      403     {object}  ErrorResponse
// @Failure      500     {object}  ErrorResponse
// @Router       /api/v1/shows/{name}/imports [get]
func (api *API) ListImportsOfShow(c *gin.Context) {
	showID := c.Param("show-id")
	if authorized, _ := authorizeRequestForShow(c, showID); !authorized {
		return
	}
	offset, limit, ok := getPaginationParameter(c)
	if !ok {
		return
	}

	jobs, err := api.importer.ListJobs(showID, offset, limit)
	if err != nil {
		sendError(c, err)
		return
	}
	c.JSON(http.StatusOK, JobsListing{jobs})
}

// ReadImportOfFile retrieves import status of the file.
// @Summary      Retrieve import status
// @Description  Retrieves import status of the file.
// @Produce      json
// @Param        name      path      string  true   "Name of the show"
// @Param        id        path      int     true   "ID of the file"
// @Param        wait-for  query     string  false  "running|done - If given, return not before import has the given state"
// @Success      200       {object}  importer.Job
// @Failure      400       {object}  ErrorResponse
// @Failure      403       {object}  ErrorResponse
// @Failure      404       {object}  ErrorResponse  "No job for this file"
// @Failure      500       {object}  ErrorResponse
// @Router       /api/v1/shows/{name}/files/{id}/import [get]
func (api *API) ReadImportOfFile(c *gin.Context) {
	showID := c.Param("show-id")
	if authorized, _ := authorizeRequestForShow(c, showID); !authorized {
		return
	}

	id, err := idFromString(c.Param("file-id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, ErrorResponse{Error: "invalid file-id: " + err.Error()})
		return
	}

	waitFor := c.Query("wait-for")
	switch waitFor {
	case "running":
	case "done":
	case "":
	default:
		c.JSON(http.StatusBadRequest, ErrorResponse{Error: "unable to wait for unknown state: " + waitFor})
		return
	}

	job, err := api.importer.GetJob(showID, id)
	if err != nil {
		// TODO: return import info from store if err == ErrNotFound
		sendError(c, err)
		return
	}

	switch waitFor {
	case "running":
		<-job.Running()
	case "done":
		<-job.Done()
	}
	c.JSON(http.StatusOK, job)
}

// CancelImportOfFile cancels import of file.
// @Summary      Cancel file import
// @Description  Cancels import of file.
// @Param        name  path      string  true  "Name of the show"
// @Param        id    path      int     true  "ID of the file"
// @Success      204
// @Failure      400   {object}  ErrorResponse
// @Failure      403   {object}  ErrorResponse
// @Failure      404   {object}  ErrorResponse  "No job for this file"
// @Failure      500   {object}  ErrorResponse
// @Router       /api/v1/shows/{name}/files/{id}/import [delete]
func (api *API) CancelImportOfFile(c *gin.Context) {
	showID := c.Param("show-id")
	if authorized, _ := authorizeRequestForShow(c, showID); !authorized {
		return
	}

	id, err := idFromString(c.Param("file-id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, ErrorResponse{Error: "invalid file-id: " + err.Error()})
		return
	}
	job, err := api.importer.GetJob(showID, id)
	if err != nil {
		sendError(c, err)
		return
	}
	job.Cancel()
	c.JSON(http.StatusNoContent, nil)
}