using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Logging;
using AyaNova.Models;
using AyaNova.Api.ControllerHelpers;
using AyaNova.Biz;


namespace AyaNova.Api.Controllers
{

    /// <summary>
    /// ServerJob controller
    /// </summary>
    [ApiController]
    [ApiVersion("8.0")]
    [Route("api/v{version:apiVersion}/job-operations")]
    [Produces("application/json")]
    [Authorize]
    public class JobOperationsController : ControllerBase
    {
        private readonly AyContext ct;
        private readonly ILogger<JobOperationsController> log;
        private readonly ApiServerState serverState;


        /// <summary>
        /// ctor
        /// </summary>
        /// <param name="dbcontext"></param>
        /// <param name="logger"></param>
        /// <param name="apiServerState"></param>
        public JobOperationsController(AyContext dbcontext, ILogger<JobOperationsController> logger, ApiServerState apiServerState)
        {
            ct = dbcontext;
            log = logger;
            serverState = apiServerState;
        }





        /// <summary>
        /// Get Operations jobs list
        /// </summary>
        /// <returns>List of operations jobs</returns>    
        [HttpGet]
        public async Task<IActionResult> List()
        {
            if (serverState.IsClosed)
                return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));

            if (!Authorized.HasReadFullRole(HttpContext.Items, AyaType.ServerJob))
            {
                return StatusCode(403, new ApiNotAuthorizedResponse());
            }

            if (!ModelState.IsValid)
            {
                return BadRequest(new ApiErrorResponse(ModelState));
            }

            //Instantiate the business object handler
            JobOperationsBiz biz = new JobOperationsBiz(ct, UserIdFromContext.Id(HttpContext.Items), UserRolesFromContext.Roles(HttpContext.Items));

            List<JobOperationsFetchInfo> l = await biz.GetJobListAsync();
            return Ok(ApiOkResponse.Response(l));
        }


        /// <summary>
        /// Get current job status for a job
        /// </summary>       
        /// <param name="gid"></param>
        /// <returns>A single job's current status</returns>
        [HttpGet("status/{gid}")]
        public async Task<IActionResult> GetJobStatus([FromRoute] Guid gid)
        {
            //this is called from things that might be running and have server temporarily locked down (e.g. seeding)
            //so it should never return an error on closed
            // if (serverState.IsClosed)
            //     return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));

            //This is called by the UI to monitor any operation that triggers a job so it really should be available to any logged in user
            // if (!Authorized.HasReadFullRole(HttpContext.Items, AyaType.ServerJob))
            // {
            //     return StatusCode(403, new ApiNotAuthorizedResponse());
            // }

            if (!ModelState.IsValid)           
                return BadRequest(new ApiErrorResponse(ModelState));
            return Ok(ApiOkResponse.Response(await JobsBiz.GetJobStatusAsync(gid)));
        }



        /// <summary>
        /// Get Operations log for a job
        /// </summary>       
        /// <param name="gid"></param>
        /// <returns>A single job's log</returns>
        [HttpGet("logs/{gid}")]
        public async Task<IActionResult> GetLogs([FromRoute] Guid gid)
        {
            if (serverState.IsClosed)
                return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));

            if (!Authorized.HasReadFullRole(HttpContext.Items, AyaType.ServerJob))
            {
                return StatusCode(403, new ApiNotAuthorizedResponse());
            }

            if (!ModelState.IsValid)
            {
                return BadRequest(new ApiErrorResponse(ModelState));
            }

            //Instantiate the business object handler
            JobOperationsBiz biz = new JobOperationsBiz(ct, UserIdFromContext.Id(HttpContext.Items), UserRolesFromContext.Roles(HttpContext.Items));

            List<JobOperationsLogInfoItem> l = await biz.GetJobLogListAsync(gid);
            return Ok(ApiOkResponse.Response(l));
        }


        /// <summary>
        /// Get Operations log for all jobs
        /// </summary>       

        /// <returns>Log for all jobs in system</returns>
        [HttpGet("logs/all-jobs")]
        public async Task<IActionResult> GetAllLogs()
        {
            if (serverState.IsClosed)
                return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));

            if (!Authorized.HasReadFullRole(HttpContext.Items, AyaType.ServerJob))
            {
                return StatusCode(403, new ApiNotAuthorizedResponse());
            }

            if (!ModelState.IsValid)
            {
                return BadRequest(new ApiErrorResponse(ModelState));
            }

            //Instantiate the business object handler
            JobOperationsBiz biz = new JobOperationsBiz(ct, UserIdFromContext.Id(HttpContext.Items), UserRolesFromContext.Roles(HttpContext.Items));

            List<JobOperationsLogInfoItem> l = await biz.GetAllJobsLogsListAsync();
            return Ok(ApiOkResponse.Response(l));
        }


        /// <summary>
        /// Trigger a test job that simulates a (30 second) long running operation for testing and ops confirmation
        /// </summary>
        /// <returns>Job id</returns>
        [HttpPost("test-job")]
        public async Task<IActionResult> TestWidgetJob()
        {
            if (!serverState.IsOpen)
                return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
            if (!Authorized.HasModifyRole(HttpContext.Items, AyaType.ServerJob))
                return StatusCode(403, new ApiNotAuthorizedResponse());
            OpsJob j = new OpsJob();
            j.Name = "TestJob";
            j.JobType = JobType.TestJob;
            await JobsBiz.AddJobAsync(j);
            await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.ServerJob, AyaEvent.Created, $"{j.JobType} {j.Name}"), ct);
            return Accepted(new { JobId = j.GId });//202 accepted
        }

        //------------






    }//eoc
}//eons