using System;
using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;

namespace Quadarax.Foundation.Core.IO
{
    public class FileSearchComparer
    {
        private IEnumerable<string> _includePatterns;
        private IEnumerable<string> _excludePatterns;

        public FileSearchComparer(IEnumerable<string> includePatterns, IEnumerable<string> excludePatterns)
        {
            _includePatterns = includePatterns ?? throw new ArgumentNullException(nameof(includePatterns));
            _excludePatterns = excludePatterns ?? throw new ArgumentNullException(nameof(excludePatterns));
        }

        public bool Match(string fullFilePath)
        {
            var result = false;
            foreach (var inclPat in _includePatterns)
            {
                if (MatchInternal(fullFilePath, inclPat))
                {
                    result = true;
                    break;
                }
            }
            foreach (var exclPat in _excludePatterns)
            {
                if (MatchInternal(fullFilePath, exclPat))
                {
                    result = false;
                    break;
                }
            }
            return result;
        }

        private bool MatchInternal(string fullFilePath, string pattern)
        {
            if (string.IsNullOrEmpty(fullFilePath) && pattern == "*")
                return true;
            if (pattern == "*")
                return true;
            if (string.IsNullOrEmpty(fullFilePath))
                return false;

            var inputChrs = fullFilePath.ToCharArray();
            var patternChrs = pattern.ToCharArray();
            var c = 0;
            for (var i = c; i< patternChrs.Length; i++)
            {
                if (i - 1 >= 0 && pattern[i-1] == '*')
                {
                    c = Array.IndexOf(inputChrs,pattern[i], c);
                    if (c == -1)
                        return false;
                }

                if (pattern[i] == inputChrs[c])
                {
                    if (c < i)
                        c = i;
                    else
                        c++;
                    continue;
                }

                if (pattern[i] != '*')
                    return false;

            }

            return true;
        }
    }
}
