<commit_before>﻿using Castle.MicroKernel;
using Ferret.Core.CommandParser.Options;
using Ferret.Core.DependencyInjection;
using Ferret.Core.Ksn;
using Microtef.Core;
using Pinpad.Sdk.Model;
using Pinpad.Sdk.Model.TypeCode;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;

namespace Ferret.Core.Services
{
    internal sealed class PinpadScanService : CoreService<ScanOption>, IPinpadService
    {
        public override string CommandName => "scan";

        // TODO: Implementar.
        public override void ConcreteExecute()
        {
            if (this.Validate() == false) { return; }

            ICollection<ICardPaymentAuthorizer> pinpadsToScan;

            if (this.TryGetPinpadsToScan(out pinpadsToScan) == false) { return; }

            List<Acquirer> acquirers = new List<Acquirer>();

            foreach (ICardPaymentAuthorizer currentPinpad in pinpadsToScan)
            {
                acquirers.AddRange(this.GetAcquirersFromPinpad(currentPinpad));
            }

            if (string.IsNullOrEmpty(this.Options.SpecificAcquirerName) == false)
            {
                AcquirerCode searchedAcquirer = this.Options.SpecificAcquirerName
                    .ToAcquirerCode();

                if (searchedAcquirer != AcquirerCode.Undefined)
                {
                    Console.WriteLine("{0} is supported!", this.Options
                        .SpecificAcquirerName.ToUpper());

                    pinpadsToScan.ShowKsn(acquirers
                        .Where(a => a.AcquirerCode == searchedAcquirer)
                        .FirstOrDefault());
                }
            }
            else
            {
                pinpadsToScan.ShowKsns(acquirers);
            }
        }

        private bool TryGetPinpadsToScan(out ICollection<ICardPaymentAuthorizer> pinpadsToScan)
        {
            if (this.Options.ScanAll == true)
            {
                pinpadsToScan = IoC.Container.Resolve<ICollection<ICardPaymentAuthorizer>>();
            }
            else if (string.IsNullOrEmpty(this.Options.PinpadToScanConnectionName) == false)
            {
                ICardPaymentAuthorizer pinpadToScan = IoC.Container.Resolve<ICollection<ICardPaymentAuthorizer>>()
                    .Where(p => p.PinpadFacade.Communication.ConnectionName == this.Options.PinpadToScanConnectionName)
                    .FirstOrDefault();

                if (pinpadToScan == null)
                {
                    Console.WriteLine("Pinpad not found at port {0}.", this.Options.PinpadToScanConnectionName);
                    pinpadsToScan = null;
                    return false;
                }

                pinpadsToScan = new Collection<ICardPaymentAuthorizer>();
                pinpadsToScan.Add(pinpadToScan);
            }
            else
            {
                Console.WriteLine("COM port name is missing.");
                pinpadsToScan = null;
                return false;
            }

            return true;
        }
        internal List<Acquirer> GetAcquirersFromPinpad (ICardPaymentAuthorizer pinpad)
        {
            Console.WriteLine("Scanning pinpad attached to {0}...", pinpad.PinpadFacade
                .Communication.ConnectionName);

            List<Acquirer> acquirers = new List<Acquirer>();

            for (int i = this.Options.Ranges[0]; i < this.Options.Ranges[1]; i++)
            {
                if (this.Options.ShowProgress == true)
                {
                    pinpad.PinpadFacade.Display.ShowMessage("", i.ToString(),
                        DisplayPaddingType.Center);
                }

                Acquirer newAcquirer = this.GetAcquirer(pinpad, i);

                if (newAcquirer != null)
                {
                    acquirers.Add(newAcquirer);
                }
            }
            
            return acquirers;
        }
        private Acquirer GetAcquirer (ICardPaymentAuthorizer pinpad, int index)
        {
            // Send GDU:
            string desKsn = pinpad.PinpadFacade.Infos.GetDukptSerialNumber(index, 
                CryptographyMode.DataEncryptionStandard);

            string tdesKsn = pinpad.PinpadFacade.Infos.GetDukptSerialNumber(index,
                CryptographyMode.TripleDataEncryptionStandard);
            
            // If there's no KSN in the index searched, that acquirer is not
            // available for the pinpad:
            if (string.IsNullOrEmpty(desKsn) == true && 
                string.IsNullOrEmpty(tdesKsn) == true)
            {
                return null;
            }

            // Create acquirer:
            Acquirer acquirer = new Acquirer();
            acquirer.AcquirerCode = (AcquirerCode)index;
            acquirer.Id = index;
            acquirer.Ksns = new Dictionary<CryptographyMode, string>();
            acquirer.PinpadSerialNumber = pinpad.PinpadFacade.Communication
                .ConnectionName;

            // Add KSNs:
            acquirer.Ksns.Add(CryptographyMode.DataEncryptionStandard, desKsn);
            acquirer.Ksns.Add(CryptographyMode.TripleDataEncryptionStandard, tdesKsn);

            // TODO: Mapear dados.
            return acquirer;
        }
        private bool Validate()
        {
            if (this.Options == null) { return false; }

            try
            {
                var availblePinpads = IoC.Container.Resolve<ICollection<ICardPaymentAuthorizer>>();
            }
            catch (ComponentNotFoundException)
            {
                Console.WriteLine("Connect to any pinpad first!");
                return false;
            }

            if (this.Options.ScanAll == true)
            {<commit_msg>:art: Adiciona mensagem caso o pinpad não suporte uma adquirente específica.<commit_after>﻿using Castle.MicroKernel;
using Ferret.Core.CommandParser.Options;
using Ferret.Core.DependencyInjection;
using Ferret.Core.Ksn;
using Microtef.Core;
using Pinpad.Sdk.Model;
using Pinpad.Sdk.Model.TypeCode;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;

namespace Ferret.Core.Services
{
    internal sealed class PinpadScanService : CoreService<ScanOption>, IPinpadService
    {
        public override string CommandName => "scan";

        public override void ConcreteExecute()
        {
            if (this.Validate() == false) { return; }

            ICollection<ICardPaymentAuthorizer> pinpadsToScan;

            if (this.TryGetPinpadsToScan(out pinpadsToScan) == false) { return; }

            List<Acquirer> acquirers = new List<Acquirer>();

            foreach (ICardPaymentAuthorizer currentPinpad in pinpadsToScan)
            {
                acquirers.AddRange(this.GetAcquirersFromPinpad(currentPinpad));
            }

            if (string.IsNullOrEmpty(this.Options.SpecificAcquirerName) == false)
            {
                AcquirerCode searchedAcquirer = this.Options.SpecificAcquirerName
                    .ToAcquirerCode();

                if (searchedAcquirer != AcquirerCode.Undefined)
                {
                    Console.WriteLine($"{this.Options.SpecificAcquirerName.ToUpper()} is supported!");

                    pinpadsToScan.ShowKsn(acquirers
                        .Where(a => a.AcquirerCode == searchedAcquirer)
                        .FirstOrDefault());
                }
                else
                {
                    Console.WriteLine($"{searchedAcquirer} is NOT supported by this pinpad.");
                }
            }
            else
            {
                pinpadsToScan.ShowKsns(acquirers);
            }
        }

        internal List<Acquirer> GetAcquirersFromPinpad (ICardPaymentAuthorizer pinpad)
        {
            Console.WriteLine($"Scanning pinpad attached to {pinpad.PinpadFacade.Communication.ConnectionName}...");

            List<Acquirer> acquirers = new List<Acquirer>();

            for (int i = this.Options.Ranges[0]; i < this.Options.Ranges[1]; i++)
            {
                if (this.Options.ShowProgress == true)
                {
                    pinpad.PinpadFacade.Display.ShowMessage("", i.ToString(),
                        DisplayPaddingType.Center);
                }

                Acquirer newAcquirer = this.GetAcquirer(pinpad, i);

                if (newAcquirer != null)
                {
                    acquirers.Add(newAcquirer);
                }
            }
            
            return acquirers;
        }

        private bool TryGetPinpadsToScan(out ICollection<ICardPaymentAuthorizer> pinpadsToScan)
        {
            if (this.Options.ScanAll == true)
            {
                pinpadsToScan = IoC.Container.Resolve<ICollection<ICardPaymentAuthorizer>>();
            }
            else if (string.IsNullOrEmpty(this.Options.PinpadToScanConnectionName) == false)
            {
                ICardPaymentAuthorizer pinpadToScan = IoC.Container.Resolve<ICollection<ICardPaymentAuthorizer>>()
                    .Where(p => p.PinpadFacade.Communication.ConnectionName == this.Options.PinpadToScanConnectionName)
                    .FirstOrDefault();

                if (pinpadToScan == null)
                {
                    Console.WriteLine($"Pinpad not found at port {this.Options.PinpadToScanConnectionName}.");
                    pinpadsToScan = null;
                    return false;
                }

                pinpadsToScan = new Collection<ICardPaymentAuthorizer>();
                pinpadsToScan.Add(pinpadToScan);
            }
            else
            {
                Console.WriteLine("COM port name is missing.");
                pinpadsToScan = null;
                return false;
            }

            return true;
        }

        private Acquirer GetAcquirer (ICardPaymentAuthorizer pinpad, int index)
        {
            // Send GDU:
            string desKsn = pinpad.PinpadFacade.Infos.GetDukptSerialNumber(index, 
                CryptographyMode.DataEncryptionStandard);

            string tdesKsn = pinpad.PinpadFacade.Infos.GetDukptSerialNumber(index,
                CryptographyMode.TripleDataEncryptionStandard);
            
            // If there's no KSN in the index searched, that acquirer is not
            // available for the pinpad:
            if (string.IsNullOrEmpty(desKsn) == true && 
                string.IsNullOrEmpty(tdesKsn) == true)
            {
                return null;
            }

            // Create acquirer:
            Acquirer acquirer = new Acquirer();
            acquirer.AcquirerCode = (AcquirerCode)index;
            acquirer.Id = index;
            acquirer.Ksns = new Dictionary<CryptographyMode, string>();
            acquirer.PinpadSerialNumber = pinpad.PinpadFacade.Communication
                .ConnectionName;

            // Add KSNs:
            acquirer.Ksns.Add(CryptographyMode.DataEncryptionStandard, desKsn);
            acquirer.Ksns.Add(CryptographyMode.TripleDataEncryptionStandard, tdesKsn);

            // TODO: Mapear dados.
            return acquirer;
        }

        private bool Validate()
        {
            if (this.Options == null) { return false; }

            try
            {
                var availblePinpads = IoC.Container.Resolve<ICollection<ICardPaymentAuthorizer>>();
            }
            catch (ComponentNotFoundException)
            {
                Console.WriteLine("Connect to any pinpad first!");
                return false;
            }

            if (this.Options.ScanAll == true)
            {
{'fraction_non_alphanumeric': 0.08541200756924136, 'fraction_numerical': 0.0006020987441940478, 'mean_word_length': 1.663078332569858, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 41, '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': '2226467', 'n_tokens_mistral': 3178, 'n_tokens_neox': 3015, 'n_words': 543}