using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.ServiceModel;

using BeWo.Data.Access;
using BeWo.Data.Entities;
using BeWo.Service.Core;
using BeWo.Service.DCEntityMapper;
using BeWo.Service.MessageContracts;
using BeWo.Service.ServiceContracts;

using BS.Shared;
using BS.Shared.DataContracts;

namespace BeWo.Service.ServiceImplementations
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
    public class StreamingServiceImp : IStreamingService
    {
        public void DeactivateBeWoFolders(List<BeWoFolderDC> dcs)
        {
            try
            {
                ServiceLogic.SetActivationType<BeWoFolder>(dcs.ToDictionary(i => i.BeWoFolderOid.Value, i => i.BeWoFolderVersion.Value), ActivationTypeId.Deleted);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<BeWoFolderDC> GetAllBeWoFolders()
        {
            try
            {
                return MapperFactory.BeWoFolderDC_BeWoFolder.MapToNewDCs(DAOFactory.GenericDAO.GetAllActive<BeWoFolder>());
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<long> InsertNewBeWoFolders(List<BeWoFolderDC> dcs)
        {
            try
            {
                var newBeWoFolders = MapperFactory.BeWoFolderDC_BeWoFolder.MapToNewEntities(dcs);
                DAOFactory.GenericDAO.Insert(newBeWoFolders);
                return newBeWoFolders.Select(i => i.Oid.Value).ToList();
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void UpdateBeWoFolders(List<BeWoFolderDC> dcs)
        {
            try
            {
                var originals = DAOFactory.GenericDAO.LoadByIDs<BeWoFolder>(dcs.Select(i => i.BeWoFolderOid.Value));
                MapperFactory.BeWoFolderDC_BeWoFolder.MergeWithEntitys(dcs, originals);
                DAOFactory.GenericDAO.Update(originals);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public UploadResult UploadDocument(UploadPackage pUpload)
        {
            //try
            //{
            var lEntity = new FileAttachment
                {
                    IsLocked = false,
                    Path = pUpload.FileName,
                    Notice = pUpload.Notice,
                    ObjectTid = (TableID)pUpload.TableID,
                    ObjectOid = pUpload.ObjectOid,
                    BeWoFolderOid = pUpload.BeWoFolderOid,
                    Data = BS.Shared.Core.Utils.ReadFully(pUpload.Stream),
                    Type = (FileAttachmentType)pUpload.FileAttachmentTypeId
                };

            pUpload.Stream.Close();
            pUpload.Stream.Dispose();




            long maxSize = 20 * 1024 * 1024;
            var maxSizeConfig = ConfigurationManager.AppSettings.Get("MaxDocumentSize");
            if (!String.IsNullOrEmpty(maxSizeConfig))
            {
                long s = 0;
                if (Int64.TryParse(maxSizeConfig, out s))
                {
                    maxSize = s;
                }
            }

            if (lEntity.Data != null && lEntity.Data.Length > 0)
            {
                if (lEntity.Data.Length > maxSize)
                {
                    throw new FaultException<BeWoFault>(new BeWoFault(
                        String.Format("Fehler beim Speichern des Dokuments. Das Dokument überschreitet die maximale erlaubte Größe.\nDie maximale Größe liegt bei {0:0.##} MB", maxSize / (1024 * 1024)), BeWoFaultType.Unknown));
                }
                DAOFactory.GenericDAO.Insert(lEntity);
            }
            else
            {
                throw new FaultException<BeWoFault>(new BeWoFault("Fehler beim Speichern des Dokuments. Das Dokument enthält keine Daten.", BeWoFaultType.Unknown));
            }

            try
            {
                var a = MapperFactory.FileAttachmentDC_FileAttachmentInfo.MapToNewDC(DAOFactory.GenericDAO.LoadByID<FileAttachmentInfo>(lEntity.Oid.Value));

                return new UploadResult { Attachment = a };
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }

        }

        public UploadResult UpdateDocument(UpdatePackage pUpload)
        {
            try
            {
                var pFileId = pUpload.FileOid;

                var original = DAOFactory.GenericDAO.GetByID<FileAttachment>(pFileId);

                original.IsLocked = false;
                original.Path = pUpload.FileName;
                original.Notice = pUpload.Notice;
                original.ObjectTid = (TableID) pUpload.TableID;
                original.ObjectOid = pUpload.ObjectOid;
                original.BeWoFolderOid = pUpload.BeWoFolderOid;
                original.Data = BS.Shared.Core.Utils.ReadFully(pUpload.Stream);
                original.Type = (FileAttachmentType) pUpload.FileAttachmentTypeId;
                
                pUpload.Stream.Close();
                pUpload.Stream.Dispose();

                if (original.Data != null && original.Data.Length > 0)
                {
                    DAOFactory.GenericDAO.Update(original);
                }
                else
                {
                    throw new FaultException<BeWoFault>(new BeWoFault("Fehler beim Speichern des Dokuments. Das Dokument enthält keine Daten.", BeWoFaultType.Unknown));
                }

                return new UploadResult { Attachment = MapperFactory.FileAttachmentDC_FileAttachment.MapToNewDC(original) };
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }
    }
}