﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;

namespace Oni
{
    internal abstract class Exporter
    {
        private readonly InstanceFileManager fileManager;
        private readonly string outputDirPath;
        private readonly Dictionary<string, string> fileNames;
        private Regex nameFilter;

        protected Exporter(InstanceFileManager fileManager, string outputDirPath)
        {
            this.fileManager = fileManager;
            this.outputDirPath = outputDirPath;
            this.fileNames = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
        }

        public InstanceFileManager InstanceFileManager => fileManager;

        public string OutputDirPath => outputDirPath;

        public Regex NameFilter
        {
            get { return nameFilter; }
            set { nameFilter = value; }
        }

        public void ExportFiles(IEnumerable<string> sourceFilePaths)
        {
            Directory.CreateDirectory(outputDirPath);

            foreach (var sourceFilePath in sourceFilePaths)
                ExportFile(sourceFilePath);

            Flush();
        }

        protected virtual void ExportFile(string sourceFilePath)
        {
            Console.WriteLine(sourceFilePath);

            var file = fileManager.OpenFile(sourceFilePath);
            var descriptors = GetSupportedDescriptors(file);

            if (nameFilter != null)
                descriptors = descriptors.FindAll(x => x.HasName && nameFilter.IsMatch(x.FullName));

            foreach (var descriptor in descriptors)
                ExportInstance(descriptor);
        }

        protected abstract void ExportInstance(InstanceDescriptor descriptor);

        protected virtual void Flush()
        {
        }

        protected virtual List<InstanceDescriptor> GetSupportedDescriptors(InstanceFile file)
        {
            return file.GetNamedDescriptors();
        }

        protected string CreateFileName(InstanceDescriptor descriptor, string fileExtension)
        {
            string name = Importer.EncodeFileName(descriptor.FullName, fileNames);
            return Path.Combine(outputDirPath, name + fileExtension);
        }
    }
}
