using System.Collections.Generic;
using System.Linq;
using isn.Controllers;
using isn.Data;
using Microsoft.EntityFrameworkCore;
using NuGet.Versioning;
using Unleash;

namespace isnd.Services
{
    public class PackageManager
    {
        ApplicationDbContext dbContext;
        public PackageManager(ApplicationDbContext dbContext)
        {
            this.dbContext = dbContext;
        }
        public IndexResult SearchByName(string query, 
             int skip, int take,bool prerelease = false, 
             string packageType = null)
        {
            var scope = dbContext.Packages
                .Include(p => p.Versions)
                .Where(
                    p => (CamelCaseMatch(p.Id, query) || SeparatedByMinusMatch(p.Id, query))
                    && (prerelease || p.Versions.Any(v => !v.IsPrerelease))
                    && (packageType == null || p.Versions.Any(v => v.Type == packageType))
                );
            return new IndexResult
                {
                    totalHits = scope.Count(),
                    data = scope.OrderBy(p => p.Id)
                    .Skip(skip).Take(take).ToArray()
                };
        }
        public AutoCompleteResult AutoComplete (string id, 
             int skip, int take, bool prerelease = false, 
             string packageType = null)
        {
            var scope = dbContext.PackageVersions.Where(
                         v => v.PackageId == id
                            && (prerelease || !v.IsPrerelease)
                            && (packageType == null || v.Type == packageType)
                     )
                     .OrderBy(v => v.FullString);
            return new AutoCompleteResult
                {
                    totalHits = scope.Count(),
                    data = scope.Select(v => v.FullString)
                     .Skip(skip).Take(take).ToArray()
                };
        }

        // TODO stocker MetaData plutôt que FullString en base,
        // et en profiter pour corriger ce listing
        public string[] GetVersions(
            string id,
            NuGetVersion parsedVersion,
            bool prerelease = false,
            string packageType = null,
            int skip = 0,
            int take = 25)
        {
            return dbContext.PackageVersions.Where(
                         v => v.PackageId == id
                            && (prerelease || !v.IsPrerelease)
                            && (packageType == null || v.Type == packageType)
                            && (parsedVersion.CompareTo(new SemanticVersion(v.Major, v.Minor, v.Patch)) < 0)
                     )
                     .OrderBy(v => v.FullString)
                     .Select(v => v.FullString)
                     .Skip(skip).Take(take).ToArray();
        }

        protected static bool CamelCaseMatch(string id, string q)
        {
            // Assert.False (q==null);
            string query = q;
            if (query.Length == 0) return false;

            while (id.Length > 0)
            {
                int i = 0;
                while (id.Length > i && char.IsLower(id[i])) i++;
                if (i == 0) break;
                id = id.Substring(i);
                if (id.StartsWith(q, System.StringComparison.OrdinalIgnoreCase)) return true;
            }
            return false;
        }
        protected static bool SeparatedByMinusMatch(string id, string q)
        {
            foreach (var part in id.Split('-'))
            {
                if (part.StartsWith(q, System.StringComparison.OrdinalIgnoreCase)) return true;
            }
            return false;
        }

        internal List<Resource> GetResources(IUnleash unleashClient)
        {
            var res = new List<Resource>();
            if (unleashClient.IsEnabled("pkg-push"))
                res.Add(
                    new Resource
                    {
                        id = "package",
                        type = "PackagePublish/2.0.0",
                        comment = "Package Publish service"
                    });
            if (unleashClient.IsEnabled("pkg-get"))
                res.Add(
                    new Resource
                    {
                        id = "package",
                        type = "PackageBaseAddress/3.0.0",
                        comment = "Package Base Address service"
                    });
            if (unleashClient.IsEnabled("pkg-autocomplete"))
                res.Add(
                    new Resource
                    {
                        id = "package/index.json",
                        type = "SearchAutocompleteService/3.5.0",
                        comment = "Auto complete service"
                    });
            if (unleashClient.IsEnabled("pkg-search"))
                res.Add(
                    new Resource
                    {
                        id = "package/index.json",
                        type = "SearchQueryService/3.5.0",
                        comment = "Search Query service"
                    });
            return res;

        }

    }
}