using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using MemoQServicesClient.FileManagerService;

namespace MemoQServicesClient
{
class FileManager
{
    /// <summary>
    /// Uploads a file given by its path.
    /// </summary>
    /// <param name="fmService">The IFileManagerService service proxy.</param>
    /// <param name="filePath">The file path.</param>
    /// <returns>The Guid of the uploaded file.</returns>
    public static Guid UploadFile(IFileManagerService fmService, string filePath)
    {
        FileStream fileStream = null;
        Guid fileGuid = Guid.Empty;
        const int chunkSize = 500000;
        byte[] chunkBytes = new byte[chunkSize];
        byte[] dataToUpload;
        int bytesRead;

        try
        {
            // Open souce file stream
            fileStream = File.OpenRead(filePath);

            // Begin chunked upload
            fileGuid = fmService.BeginChunkedFileUpload(filePath, false);

            // Upload chunks
            while ((bytesRead = fileStream.Read(chunkBytes, 0, chunkSize)) != 0)
            {
                if (bytesRead == chunkSize)
                    dataToUpload = chunkBytes;
                else
                {
                    // If we are at the end, we want to upload only
                    // the bytes read from the stream.
                    dataToUpload = new byte[bytesRead];
                    Array.Copy(chunkBytes, dataToUpload, bytesRead);
                }
                fmService.AddNextFileChunk(fileGuid, dataToUpload);
            }

            return fileGuid;
        }
        finally
        {
            if (fileStream != null)
                fileStream.Close();

            // End chunked upload
            if (fileGuid != Guid.Empty)
                fmService.EndChunkedFileUpload(fileGuid);

        }
    }

    /// <summary>
    /// Downloads a file given by its Guid.
    /// </summary>
    /// <param name="fmService">The IFileManagerService service proxy.</param>
    /// <param name="fileGuid">The file GUID.</param>
    /// <param name="fileName">Name of the file.</param>
    /// <param name="targetdir">The target directory.</param>
    public static void DownloadFile(IFileManagerService fmService, Guid fileGuid,
        out string fileName, string targetdir)
    {
        FileStream fileStream = null;
        Guid sessionGuid = Guid.Empty;
        const int chunkSize = 500000;
        byte[] chunkBytes;
        int fileSize;
        int fileBytesLeft;

        try
        {
            sessionGuid = fmService.BeginChunkedFileDownload(out fileName,
                out fileSize, fileGuid, false);
            fileStream = new FileStream(Path.Combine(targetdir, fileName),
                FileMode.Create);
            fileBytesLeft = fileSize;

            while (fileBytesLeft > 0)
            {
                chunkBytes = fmService.GetNextFileChunk(sessionGuid, chunkSize);
                fileStream.Write(chunkBytes, 0, chunkBytes.Length);
                fileBytesLeft -= chunkBytes.Length;
            }
        }
        finally
        {
            if (fileStream != null)
                fileStream.Close();

            try
            {
                if (sessionGuid != Guid.Empty)
                    fmService.EndChunkedFileDownload(sessionGuid);

                // We no longer need the file, delete it on the server.
                fmService.DeleteFile(fileGuid);
            }
            catch (Exception)
            {
                //Log.WriteVerbose(e.ToString());
                // We are not interested in these errors. And don't want the
                // original error to be hidden by these exceptions.
            }
        }
    }
}
}
