/* Metodos abaixo para gerar Json a ser utilizado na aplicação */

        public Task SalvarStatusTransacao(ControladorLog log)
        {
            List <ControladorLog> trans = new List <ControladorLog>();

            using (StreamReader r = new StreamReader(string.Format("{0}.json", Util.DiretorioTransacoesQuarto)))
            {
                //Converto em JSON
                string json = r.ReadToEnd();
                trans = JsonConvert.DeserializeObject <List <ControladorLog> >(json);

                if (trans == null)
                {
                    trans = new List <ControladorLog>();
                }
            }

            trans.Add(log);

            using (StreamWriter file = System.IO.File.CreateText(string.Format("{0}.json", Util.DiretorioTransacoesQuarto)))
            {
                JsonSerializer serializer = new JsonSerializer();
                //SALVO LOG DA TRANSAÇÃO
                serializer.Serialize(file, trans);
            }

            return(Task.CompletedTask);
        }
        public IActionResult ReservarCirurgia([FromBody] ReservaModel reserva)
        {
            RequestProvider.RequestProvider request = new RequestProvider.RequestProvider();

            //bloqueio de Reserva.
            //Garante que um thread não insere uma seção crítica do código enquanto outro thread está na seção crítica.
            //Se outro request tentar inserir uma reserva, ele aguardará, bloqueado, até que o objeto dentro da seção seja liberado.
            lock (reserva) //Métodos	de	Controle	de	Concorrência:	 Travas	(locks)	e	bloqueios;
            {
                string         reservaCirurgiaoId;
                string         reservarAnestesista;
                DateTime       inicio = DateTime.Now;
                ControladorLog log    = new ControladorLog(Guid.NewGuid());


                try
                {
                    #region Primeira fase: Fase de Votação
                    try
                    {
                        reservarAnestesista = _apiAnestesista.ReservarAnestesista(reserva.Anestesista, log.GuidTransaction.ToString()).Result;
                        log.AlterarStatusAnestesista(EStatus.Preparado);
                    }
                    catch (Exception ex)
                    {
                        //Se der erro no momento de reservar anestesista, retorna para usuário BAD request e não continua com a transação
                        log.FinalizarTransacao();
                        SalvarStatusTransacao(log);

                        throw ex;
                    }

                    try
                    {
                        reservaCirurgiaoId = _apiCirurgiao.ReservarCirurgiao(reserva.Cirurgiao, log.GuidTransaction.ToString()).Result;
                        log.AlterarStatusCirurgiao(EStatus.Preparado);
                    }
                    catch (Exception ex)
                    {
                        log.AlterarStatusAnestesista(EStatus.AguardandoAbertar);
                        var res = _apiAnestesista.RollBack(reservarAnestesista).Result;
                        log.AlterarStatusAnestesista(EStatus.Abortado);

                        SalvarStatusTransacao(log);

                        throw ex;
                    }
                    #endregion Primeira fase: Fase de Votação

                    #region Segunda fase: Fase de Decisão

                    //Se não houve erro em nenhum dos passos acima, realiza a reserva do quarto -> caso ocorra erros (rollback nas transações anteriores).


                    //Reservar quarto () -> Codigo.

                    try
                    {
                        bool quarto = AgendarQuarto(reserva.Quarto);
                        //  LogControlador(reservarAnestesista, reservaCirurgiaoId, inicio);


                        if (!quarto)
                        {
                            log.AlterarStatusAnestesista(EStatus.AguardandoAbertar);
                            log.AlterarStatusCirurgiao(EStatus.AguardandoAbertar);

                            var res   = _apiAnestesista.RollBack(reservarAnestesista).Result;
                            var teste = _apiCirurgiao.RollBack(reservaCirurgiaoId).Result;

                            log.AlterarStatusCirurgiao(EStatus.AguardandoAbertar);
                            log.AlterarStatusAnestesista(EStatus.AguardandoAbertar);

                            return(BadRequest());
                        }
                    }

                    catch (Exception ex)
                    {
                        SalvarStatusTransacao(log);

                        throw ex;
                    }


                    //Se não houve erro em nenhum dos passos acima, commita as transações

                    try
                    {
                        log.AlterarStatusAnestesista(EStatus.AguardandoEfetivacao);
                        log.AlterarStatusCirurgiao(EStatus.AguardandoEfetivacao);

                        var res1 = _apiCirurgiao.Commit(reservaCirurgiaoId).Result;
                        var res2 = _apiAnestesista.Commit(reservarAnestesista).Result;

                        log.AlterarStatusAnestesista(EStatus.Efetivado);
                        log.AlterarStatusCirurgiao(EStatus.Efetivado);

                        SalvarStatusTransacao(log);
                    }

                    catch (Exception x)             //Reetentiva
                    {
                        SalvarStatusTransacao(log); //Salva status para o processo se recompor.
                    }
                    //Commit();
                    #endregion Segunda fase: Fase de Decisão

                    //Retorna que a request foi OK ... Status Code 200.
                    return(Ok());
                }
                catch (Exception ex)
                {
                    return(BadRequest(ex.Message));
                }
            }
        }