using System;
using System.Collections.Generic;
using BO.AppServer.Metadata.Dto;
using BO.AppServer.Metadata.Enums;
using BO.Console.Commands.Workspace.Sync.Diff;
using Quadarax.Foundation.Core.Data.Diff;

namespace BO.Console.Commands.Workspace.Sync
{
    internal class DocumentEntryComparer
    {

        #region *** Private fields ***
        private IList<DocumentItem> _local = new List<DocumentItem>();
        private IList<DocumentItem> _remote = new List<DocumentItem>();
        #endregion


        #region *** Public Operations ***
        public void AddLocalDocument(string directoryName, string fileName, long fileSize)
        {
            var doc = ParseDocumentDirectory(directoryName);
            if (doc != null)
            {
                var art = ParseArtifactFileName(fileName);
                if (art != null)
                {
                    var item = new DocumentItem();
                    item.ArtName = art.Item3;
                    item.ArtExt = art.Item4;
                    item.ArtId = art.Item1;
                    item.ArtLength = fileSize;
                    item.DocId = doc.Item1;
                    item.DocName = doc.Item2;
                    item.ArtType = art.Item2.ToLower() == "input" ? ArtifactTypeEnum.Input : ArtifactTypeEnum.Output;
                    item.IsLocal = true;
                    _local.Add(item);
                }
            }
        }

        public void AddLocalDocumentNew(string fileName, bool bIn = true)
        {
        }

        public void AddRemoteDocument(DocumentRDto document)
        {
            foreach (var art in document.Artifacts)
            {
                var item = new DocumentItem();
                item.ArtName = art.Name;
                item.ArtExt = art.Extension;
                item.ArtId = art.Id;
                item.ArtLength = art.Length;
                item.DocId = document.Id;
                item.DocName = document.Name;
                item.IsLocal = false;
                art.Type = art.Type;
                _remote.Add(item);
            }
        }

        public DiffComparator<DocumentEntry> GetComparator()
        {
            return new DiffComparator<DocumentEntry>(_local, _remote);
        }

        public bool ValidateDocumentDirectory(string directoryName)
        {
            return ParseDocumentDirectory(directoryName)!=null;
        }

        public bool ValidateArtifactFileName(string artifactFileName)
        {
            return ParseArtifactFileName(artifactFileName) != null;
        }

        #endregion

        //<documentId:8>.<document_name_normalized>
        private Tuple<long, string> ParseDocumentDirectory(string directoryName)
        {
            var parts = directoryName.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
            if (parts.Length != 2)
                return null;
            if (!long.TryParse(parts[0], out var id))
                return null;
            return new Tuple<long, string>(id, parts[1]);
        }

        // <arifact_id>.<artifact_type>.<artifact_name>.<artifaxt_ext>
        private Tuple<long, string, string, string> ParseArtifactFileName(string artifactFileName)
        {
            var parts = artifactFileName.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
            if (parts.Length != 4)
                return null;
            if (!long.TryParse(parts[0], out var id))
                return null;
            return new Tuple<long, string, string, string>(id, parts[1], parts[2], parts[3]);
        }

    }
}
