/*
shottower
Copyright (C) 2022 RÃ©my Boulanouar

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 <http://www.gnu.org/licenses/>.
*/
/*
 * Shottower
 *
 * Shottower is the open source version of Shotstack which is a video, image and audio editing service that allows for the automated generation of videos, images and audio using JSON and a RESTful API.  You arrange and configure an edit and POST it to the API which will render your media and provide a file  location when complete.  For more details visit [shottower](https://github.com/DblK/shottower) or checkout our [getting started](https://shotstack.io/docs/guide/) documentation.  There are two main API's, one for editing and generating assets (Edit API) and one for managing hosted assets (Serve API).  The Edit API base URL is: <b>http://0.0.0.0:4000/{version}</b>  The Serve API base URL is: <b>http://0.0.0.0:4000/serve/{version}</b>
 *
 * API version: stage
 * Generated by: OpenAPI Generator (https://openapi-generator.tech)
 */

package openapi

import (
	"context"
	"errors"
	"net/http"
	"time"

	"github.com/DblK/shottower/config"
	"github.com/google/uuid"
)

// EditAPIService is a service that implements the logic for the EditAPIServicer
// This service should implement the business logic for every endpoint for the EditApi API.
// Include any external packages or services that will be required by this service.
type EditAPIService struct {
	renders []*RenderQueue
	config  config.ShottowerConfiguration
}

// NewEditAPIService creates a default api service
func NewEditAPIService(cfg config.ShottowerConfiguration) EditAPIServicer {
	return &EditAPIService{
		config: cfg,
	}
}

// DeleteTemplate - Delete Template
func (s *EditAPIService) DeleteTemplate(ctx context.Context, id string) (ImplResponse, error) {
	// TODO - update DeleteTemplate with the required logic for this service method.
	// Add api_edit_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.

	//TODO: Uncomment the next line to return response Response(204, {}) or use other options such as http.Ok ...
	//return Response(204, nil),nil

	return Response(http.StatusNotImplemented, nil), errors.New("DeleteTemplate method not implemented")
}

func (s *EditAPIService) GetQueue() []*RenderQueue {
	return s.renders
}

func (s *EditAPIService) GetQueuePending() []*RenderQueue {
	filteredQueue := make([]*RenderQueue, 0)

	for _, render := range s.renders {
		if render.Status == Queued {
			filteredQueue = append(filteredQueue, render)
		}
	}
	return filteredQueue
}

// GetRender - Get Render Status
func (s *EditAPIService) GetRender(ctx context.Context, id string, data bool, merged bool) (ImplResponse, error) {
	var renderQueue *RenderQueue
	for _, n := range s.renders {
		if n.ID == id {
			renderQueue = n
		}
	}

	if renderQueue == nil {
		return Response(http.StatusNotFound, nil), errors.New("Can not find id: '" + id + "'")
	}

	var responseData = RenderResponseData{
		ID:      renderQueue.ID,
		Owner:   "me",
		Plan:    "free",
		Status:  renderQueue.Status.String(),
		Created: renderQueue.Created.Format("2006-01-02T15:04:05.123Z"),
		Updated: renderQueue.Updated.Format("2006-01-02T15:04:05.123Z"),
	}

	if renderQueue.Status == Done {
		responseData.URL = s.config.GetDownloadBaseURL() + "/renders/" + renderQueue.ID
		responseData.Duration = renderQueue.FFMPEGCommand.GetDuration()
		responseData.RenderTime = float32(renderQueue.Updated.Sub(renderQueue.Created).Milliseconds())
	}

	var response = RenderResponse{
		Success:  true,
		Message:  "OK",
		Response: responseData,
	}
	if data {
		response.Response.Data = renderQueue.Data
	}
	return Response(200, response), nil
}

// GetTemplate - Retrieve Template
func (s *EditAPIService) GetTemplate(ctx context.Context, id string) (ImplResponse, error) {
	// TODO - update GetTemplate with the required logic for this service method.
	// Add api_edit_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.

	//TODO: Uncomment the next line to return response Response(200, TemplateDataResponse{}) or use other options such as http.Ok ...
	//return Response(200, TemplateDataResponse{}), nil

	return Response(http.StatusNotImplemented, nil), errors.New("GetTemplate method not implemented")
}

// GetTemplates - List Templates
func (s *EditAPIService) GetTemplates(ctx context.Context) (ImplResponse, error) {
	// TODO - update GetTemplates with the required logic for this service method.
	// Add api_edit_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.

	//TODO: Uncomment the next line to return response Response(200, TemplateListResponse{}) or use other options such as http.Ok ...
	//return Response(200, TemplateListResponse{}), nil

	return Response(http.StatusNotImplemented, nil), errors.New("GetTemplates method not implemented")
}

// PostRender - Render Asset
func (s *EditAPIService) PostRender(ctx context.Context, edit Edit) (ImplResponse, error) {
	var newUUID, _ = uuid.NewRandom()

	// Push a new render
	s.renders = append(s.renders, &RenderQueue{
		ID:      newUUID.String(),
		Data:    edit,
		Status:  Queued,
		Created: time.Now(),
		Updated: time.Now(),
	})

	return Response(201, QueuedResponse{
		Success: true,
		Message: "Created",
		Response: QueuedResponseData{
			Message: "Render Successfully Queued",
			ID:      newUUID.String(),
		},
	}), nil
}

// PostTemplate - Create Template
func (s *EditAPIService) PostTemplate(ctx context.Context, template Template) (ImplResponse, error) {
	// TODO - update PostTemplate with the required logic for this service method.
	// Add api_edit_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.

	//TODO: Uncomment the next line to return response Response(201, TemplateResponse{}) or use other options such as http.Ok ...
	//return Response(201, TemplateResponse{}), nil

	return Response(http.StatusNotImplemented, nil), errors.New("PostTemplate method not implemented")
}

// PostTemplateRender - Render Template
func (s *EditAPIService) PostTemplateRender(ctx context.Context, templateRender TemplateRender) (ImplResponse, error) {
	// TODO - update PostTemplateRender with the required logic for this service method.
	// Add api_edit_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.

	//TODO: Uncomment the next line to return response Response(201, QueuedResponse{}) or use other options such as http.Ok ...
	//return Response(201, QueuedResponse{}), nil

	return Response(http.StatusNotImplemented, nil), errors.New("PostTemplateRender method not implemented")
}

// Probe - Inspect Media
func (s *EditAPIService) Probe(ctx context.Context, url string) (ImplResponse, error) {
	// TODO - update Probe with the required logic for this service method.
	// Add api_edit_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.

	//TODO: Uncomment the next line to return response Response(200, ProbeResponse{}) or use other options such as http.Ok ...
	//return Response(200, ProbeResponse{}), nil

	return Response(http.StatusNotImplemented, nil), errors.New("Probe method not implemented")
}

// PutTemplate - Update Template
func (s *EditAPIService) PutTemplate(ctx context.Context, id string, template Template) (ImplResponse, error) {
	// TODO - update PutTemplate with the required logic for this service method.
	// Add api_edit_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.

	//TODO: Uncomment the next line to return response Response(200, TemplateResponse{}) or use other options such as http.Ok ...
	//return Response(200, TemplateResponse{}), nil

	return Response(http.StatusNotImplemented, nil), errors.New("PutTemplate method not implemented")
}
