using System.Security;
using JamesKovacs.IoCArticle.DiyContainer.Domain;
using JamesKovacs.IoCArticle.DiyContainer.Infrastructure.Container;
using JamesKovacs.IoCArticle.DiyContainer.Repositories;

namespace JamesKovacs.IoCArticle.DiyContainer.Services {
    public class InvoiceService : IInvoiceService {
        private readonly IAuthorizationService authorizationService;
        private readonly IInvoiceValidator invoiceValidator;
        private readonly IInvoiceRepository invoiceRepository;

        public InvoiceService() : this(IoC.Resolve<IAuthorizationService>(), IoC.Resolve<IInvoiceValidator>(), IoC.Resolve<IInvoiceRepository>()) {
        }

        public InvoiceService(IAuthorizationService authorizationService, IInvoiceValidator invoiceValidator, IInvoiceRepository invoiceRepository) {
            this.authorizationService = authorizationService;
            this.invoiceValidator = invoiceValidator;
            this.invoiceRepository = invoiceRepository;
        }

        public ValidationResults Submit(Invoice invoice) {
            ValidationResults results;
            CheckPermissions(invoice, InvoiceAction.Submit);
            results = ValidateInvoice(invoice);
            SaveInvoice(invoice);
            return results;
        }

        private void CheckPermissions(Invoice invoice, InvoiceAction action) {
            if(authorizationService.IsActionAllowed(invoice, action) == false) {
                throw new SecurityException("Insufficient permissions to submit this invoice");
            }
        }

        private ValidationResults ValidateInvoice(Invoice invoice) {
            return invoiceValidator.Validate(invoice);
        }

        private void SaveInvoice(Invoice invoice) {
            invoiceRepository.Save(invoice);
        }
    }
}