<commit_before>﻿using System;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Web.Mvc;
using AutoMapper;
using NLog;
using SFA.DAS.EAS.Domain.Interfaces;
using SFA.DAS.EAS.Domain.Models.Organisation;
using SFA.DAS.EAS.Web.Authentication;
using SFA.DAS.EAS.Web.Orchestrators;
using SFA.DAS.EAS.Web.ViewModels;
using SFA.DAS.EAS.Web.ViewModels.Organisation;

namespace SFA.DAS.EAS.Web.Controllers
{
    [Authorize]
    [RoutePrefix("accounts/organisations")]
    public class EmployerAccountOrganisationController : BaseController
    {
        private readonly OrganisationOrchestrator _orchestrator;
        private readonly IMapper _mapper;
        private readonly ILogger _logger;

        public EmployerAccountOrganisationController(
            IOwinWrapper owinWrapper,
            OrganisationOrchestrator orchestrator,
            IFeatureToggle featureToggle,
            IUserWhiteList userWhiteList,
            IMapper mapper,
            ILogger logger) 
            :base(owinWrapper, featureToggle, userWhiteList)
        {
            _orchestrator = orchestrator;
            _mapper = mapper;
            _logger = logger;
        }

        [HttpGet]
        [Route("add")]
        public ActionResult AddOrganisation()
        {
            return View("AddOrganisation",
                new OrchestratorResponse<AddLegalEntityViewModel> {Data = new AddLegalEntityViewModel()});
        }
        
        [HttpPost]
        [ValidateAntiForgeryToken]
        [Route("add")]
        public async Task<ActionResult> AddOrganisation(AddLegalEntityViewModel model)
        {
            if (!ModelState.IsValid)
            {
                var orgTypeErrorResponse = new OrchestratorResponse<AddLegalEntityViewModel>
                {
                    Data = model
                };

                orgTypeErrorResponse.Data.AddErrorsFromModelState(ModelState);

                orgTypeErrorResponse.Status = HttpStatusCode.BadRequest;
                orgTypeErrorResponse.FlashMessage = new FlashMessageViewModel
                {
                    Severity = FlashMessageSeverityLevel.Error,
                    ErrorMessages = orgTypeErrorResponse.Data.ErrorDictionary,
                    Headline = "Errors to fix",
                    Message = "Check the following details:"
                };
                return View(orgTypeErrorResponse);
            }

            OrchestratorResponse<OrganisationDetailsViewModel> response;

            //TODO this can be removed once we determine which is slow in prod
            var stopwatch = new System.Diagnostics.Stopwatch();
            try
            {
                
                stopwatch.Start();
                switch (model.OrganisationType)
                {
                    case OrganisationType.Charities:
                        response = await FindCharity(model.CharityRegistrationNumber, model.HashedAccountId, OwinWrapper.GetClaimValue(@"sub"));
                        break;
                    case OrganisationType.CompaniesHouse:
                        response = await FindCompany(model.CompaniesHouseNumber, model.HashedAccountId, OwinWrapper.GetClaimValue(@"sub"));

                        break;
                    case OrganisationType.PublicBodies:
                        var searchResponse = await FindPublicSectorOrganisation(model.PublicBodyName, model.HashedAccountId, OwinWrapper.GetClaimValue(@"sub"));

                        if (searchResponse.Status == HttpStatusCode.OK)
                        {
                            if (searchResponse.Data.Results.Data.Count != 1 ||
                                searchResponse.Data.Results.Data.All(x => x.AddedToAccount))
                            {
                                return View("ViewPublicSectorOrganisationSearchResults", searchResponse);
                            }

                            response = new OrchestratorResponse<OrganisationDetailsViewModel>
                            {
                                Data = searchResponse.Data.Results.Data.FirstOrDefault(),
                                Status = searchResponse.Status
                            };
                        }
                        else
                        {
                            response = new OrchestratorResponse<OrganisationDetailsViewModel>
                            {
                                Data = new OrganisationDetailsViewModel(),
                                Status = searchResponse.Status
                            };
                            response.Data.ErrorDictionary = searchResponse.Data.ErrorDictionary;
                        }

                        break;

                    case OrganisationType.Other:

                        response = new OrchestratorResponse<OrganisationDetailsViewModel>
                        {
                            Data = new OrganisationDetailsViewModel()
                        };

                        return View("AddOtherOrganisationDetails", response);

                    default:
                        throw new NotImplementedException("Org Type Not Implemented");
                }
            }
            finally
            {
                stopwatch.Stop();

                _logger.Info($"Company Search for {model.OrganisationType} took {stopwatch.ElapsedMilliseconds *1000d}s");
            }

            

            if (response.Status == HttpStatusCode.OK)
            {
                //Removes empty address entries (i.e. ' , , ')
                var address = (response.Data?.Address ?? string.Empty).Replace(",", string.Empty);

                if (string.IsNullOrWhiteSpace(address))
                {
                    var addressViewModel = _mapper.Map<FindOrganisationAddressViewModel>(response.Data);

                    var addressResponse = new OrchestratorResponse<FindOrganisationAddressViewModel>
                    {
                        Data = addressViewModel
                    };

                    return View("FindAddress", addressResponse);<commit_msg>Correct timing for company search<commit_after>﻿using System;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Web.Mvc;
using AutoMapper;
using NLog;
using SFA.DAS.EAS.Domain.Interfaces;
using SFA.DAS.EAS.Domain.Models.Organisation;
using SFA.DAS.EAS.Web.Authentication;
using SFA.DAS.EAS.Web.Orchestrators;
using SFA.DAS.EAS.Web.ViewModels;
using SFA.DAS.EAS.Web.ViewModels.Organisation;

namespace SFA.DAS.EAS.Web.Controllers
{
    [Authorize]
    [RoutePrefix("accounts/organisations")]
    public class EmployerAccountOrganisationController : BaseController
    {
        private readonly OrganisationOrchestrator _orchestrator;
        private readonly IMapper _mapper;
        private readonly ILogger _logger;

        public EmployerAccountOrganisationController(
            IOwinWrapper owinWrapper,
            OrganisationOrchestrator orchestrator,
            IFeatureToggle featureToggle,
            IUserWhiteList userWhiteList,
            IMapper mapper,
            ILogger logger) 
            :base(owinWrapper, featureToggle, userWhiteList)
        {
            _orchestrator = orchestrator;
            _mapper = mapper;
            _logger = logger;
        }

        [HttpGet]
        [Route("add")]
        public ActionResult AddOrganisation()
        {
            return View("AddOrganisation",
                new OrchestratorResponse<AddLegalEntityViewModel> {Data = new AddLegalEntityViewModel()});
        }
        
        [HttpPost]
        [ValidateAntiForgeryToken]
        [Route("add")]
        public async Task<ActionResult> AddOrganisation(AddLegalEntityViewModel model)
        {
            if (!ModelState.IsValid)
            {
                var orgTypeErrorResponse = new OrchestratorResponse<AddLegalEntityViewModel>
                {
                    Data = model
                };

                orgTypeErrorResponse.Data.AddErrorsFromModelState(ModelState);

                orgTypeErrorResponse.Status = HttpStatusCode.BadRequest;
                orgTypeErrorResponse.FlashMessage = new FlashMessageViewModel
                {
                    Severity = FlashMessageSeverityLevel.Error,
                    ErrorMessages = orgTypeErrorResponse.Data.ErrorDictionary,
                    Headline = "Errors to fix",
                    Message = "Check the following details:"
                };
                return View(orgTypeErrorResponse);
            }

            OrchestratorResponse<OrganisationDetailsViewModel> response;

            //TODO this can be removed once we determine which is slow in prod
            var stopwatch = new System.Diagnostics.Stopwatch();
            try
            {
                
                stopwatch.Start();
                switch (model.OrganisationType)
                {
                    case OrganisationType.Charities:
                        response = await FindCharity(model.CharityRegistrationNumber, model.HashedAccountId, OwinWrapper.GetClaimValue(@"sub"));
                        break;
                    case OrganisationType.CompaniesHouse:
                        response = await FindCompany(model.CompaniesHouseNumber, model.HashedAccountId, OwinWrapper.GetClaimValue(@"sub"));

                        break;
                    case OrganisationType.PublicBodies:
                        var searchResponse = await FindPublicSectorOrganisation(model.PublicBodyName, model.HashedAccountId, OwinWrapper.GetClaimValue(@"sub"));

                        if (searchResponse.Status == HttpStatusCode.OK)
                        {
                            if (searchResponse.Data.Results.Data.Count != 1 ||
                                searchResponse.Data.Results.Data.All(x => x.AddedToAccount))
                            {
                                return View("ViewPublicSectorOrganisationSearchResults", searchResponse);
                            }

                            response = new OrchestratorResponse<OrganisationDetailsViewModel>
                            {
                                Data = searchResponse.Data.Results.Data.FirstOrDefault(),
                                Status = searchResponse.Status
                            };
                        }
                        else
                        {
                            response = new OrchestratorResponse<OrganisationDetailsViewModel>
                            {
                                Data = new OrganisationDetailsViewModel(),
                                Status = searchResponse.Status
                            };
                            response.Data.ErrorDictionary = searchResponse.Data.ErrorDictionary;
                        }

                        break;

                    case OrganisationType.Other:

                        response = new OrchestratorResponse<OrganisationDetailsViewModel>
                        {
                            Data = new OrganisationDetailsViewModel()
                        };

                        return View("AddOtherOrganisationDetails", response);

                    default:
                        throw new NotImplementedException("Org Type Not Implemented");
                }
            }
            finally
            {
                stopwatch.Stop();

                _logger.Info($"Company Search for {model.OrganisationType} took {stopwatch.ElapsedMilliseconds /1000d}s");
            }

            

            if (response.Status == HttpStatusCode.OK)
            {
                //Removes empty address entries (i.e. ' , , ')
                var address = (response.Data?.Address ?? string.Empty).Replace(",", string.Empty);

                if (string.IsNullOrWhiteSpace(address))
                {
                    var addressViewModel = _mapper.Map<FindOrganisationAddressViewModel>(response.Data);

                    var addressResponse = new OrchestratorResponse<FindOrganisationAddressViewModel>
                    {
                        Data = addressViewModel
                    };

                    return View("FindAddress", addressResponse);
{'fraction_non_alphanumeric': 0.06865137465430292, 'fraction_numerical': 0.0008134049129656743, 'mean_word_length': 1.4718536389223964, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2563128', 'n_tokens_mistral': 2844, 'n_tokens_neox': 2634, 'n_words': 501}