using System.Collections.Generic;
using System.IO;
using System.Linq;
using Inspectron.Ringbuffer.Interfaces;

namespace Inspectron.Ringbuffer
{
    /// <summary>
    ///     Ringbuffer\Product\Good\File
    /// </summary>
    public class ProductIndex : IIndex
    {
        private readonly object _lock = new object();
        private readonly Dictionary<string, ProductResults> _products = new Dictionary<string, ProductResults>();

        public void Track(string filePath)
        {
            var product = Path.GetDirectoryName(Path.GetDirectoryName(filePath)).Split(Path.DirectorySeparatorChar)
                .Last();
            var result = Path.GetDirectoryName(filePath).Split(Path.DirectorySeparatorChar).Last();
            lock (_lock)
            {
                if (!_products.ContainsKey(product))
                    _products[product] = new ProductResults
                    {
                        Good = new List<string>(),
                        Bad = new List<string>()
                    };

                if (result == RingbufferFolder.GOOD_DIR)
                {
                    if (!_products[product].Good.Contains(filePath))
                        _products[product].Good.Insert(0, filePath);
                }

                else
                {
                    if (!_products[product].Bad.Contains(filePath))
                        _products[product].Bad.Insert(0, filePath);
                }
            }
        }

        public List<string> GetFilesToDelete(int allowedAmountGood, int allowedAmountBad)
        {
            lock (_lock)
            {
                var filesToDelete = new List<string>();
                foreach (var p in _products)
                {
                    var goodToDelete = p.Value.Good.Skip(allowedAmountGood).ToList();
                    var badToDelete = p.Value.Bad.Skip(allowedAmountGood).ToList();

                    goodToDelete.ForEach(x => p.Value.Good.Remove(x));
                    badToDelete.ForEach(x => p.Value.Bad.Remove(x));
                    filesToDelete.AddRange(goodToDelete);
                    filesToDelete.AddRange(badToDelete);
                }

                return filesToDelete;
            }
        }

        private class ProductResults
        {
            public List<string> Good { get; set; }
            public List<string> Bad { get; set; }
        }
    }
}