/// <summary>
        /// Unzip a file
        /// </summary>
        /// <param name="filePath">Zip file path</param>
        /// <returns>Unzip file path</returns>
        public static string UnzipFile(string filePath)
        {
            string resultFilename = "";

            ZipArchive archive    = System.IO.Compression.ZipFile.OpenRead(filePath);
            var        zippedFile = archive.GetEntry(Path.GetFileNameWithoutExtension(filePath));

            resultFilename = Path.ChangeExtension(filePath, "").TrimEnd('.');

            if (System.IO.File.Exists(resultFilename))
            {
                System.IO.File.Delete(resultFilename);
            }

            zippedFile.ExtractToFile(resultFilename);

            archive.Dispose();

            GenericFileStorage.deleteFile(filePath);

            return(resultFilename);
        }
        /// <summary>
        /// Zip a file
        /// </summary>
        /// <param name="filename">Local file path</param>
        /// <returns>Local zip file path</returns>
        public static string ZipFile(string filename)
        {
            string zippedFilename = filename + ".zip";

            GenericFileStorage.deleteFile(zippedFilename);

            using (var memoryStream = new MemoryStream())
            {
                using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
                {
                    var demoFile = archive.CreateEntryFromFile(filename, Path.GetFileName(filename));
                }

                using (var fileStream = new FileStream(zippedFilename, FileMode.Create))
                {
                    memoryStream.Seek(0, SeekOrigin.Begin);
                    memoryStream.CopyTo(fileStream);
                }
            }

            //GenericFileStorage.deleteFile(filename);

            return(zippedFilename);
        }
        /// <summary>
        /// Download a file from the GSS
        /// </summary>
        /// <param name="fileId">gss file address</param>
        /// <param name="folderPath">local folder where the file will be download</param>
        /// <param name="filename">Force a local filename</param>
        /// <param name="autoUnzip">Unzip the file if the extension is *.zip</param>
        /// <returns></returns>
        public string DownloadFile(string fileId, string folderPath, string filename = "", bool autoUnzip = true)
        {
            if (!fileUtils.containsFile(fileId, this.SessionToken))
            {
                throw new Exception(string.Format("File \"{0}\" does not exist on the GSS", fileId));
            }

            var resourceInfo    = fileUtils.getResourceInformation(fileId, this.SessionToken);
            var readDescription = resourceInfo.readDescription;

            if (!readDescription.supported)
            {
                throw new Exception("Read operation not allowed!");
            }

            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

            HttpWebRequest downloadRequest = (HttpWebRequest)WebRequest.Create(readDescription.url);

            // We set the parameters as described by the service
            downloadRequest.Method    = readDescription.httpMethod;
            downloadRequest.Timeout   = Timeout.Infinite;
            downloadRequest.KeepAlive = true;

            if (readDescription.headers != null)
            {
                foreach (var headerField in readDescription.headers)
                {
                    downloadRequest.Headers[headerField.key] = headerField.value;
                }
            }

            // In return we will get the id of the newly created file:
            HttpWebResponse responseFromDownload = (HttpWebResponse)downloadRequest.GetResponse();

            if (responseFromDownload.StatusCode != HttpStatusCode.OK && responseFromDownload.StatusCode != HttpStatusCode.Accepted)
            {
                throw new Exception("Wrong status code returned");
            }

            string localFilePath = folderPath.TrimEnd('\\') + @"\";

            if (string.IsNullOrEmpty(filename))
            {
                localFilePath += Path.GetFileName(fileId);
            }
            else
            {
                localFilePath += filename;
            }

            //Write the server file on the computer
            using (BinaryWriter writer = new BinaryWriter(System.IO.File.OpenWrite(localFilePath), fileEncoding))
            {
                using (BinaryReader reader = new BinaryReader(responseFromDownload.GetResponseStream()))
                {
                    int    bufferSize = this.BufferSize;
                    byte[] buffer     = new byte[bufferSize];
                    while ((buffer = reader.ReadBytes(bufferSize)).GetLength(0) > 0)
                    {
                        writer.Write(buffer);
                    }
                }
            }

            if (autoUnzip && Path.GetExtension(localFilePath).ToLower().Equals(".zip"))
            {
                localFilePath = GenericFileStorage.UnzipFile(localFilePath);
            }

            return(localFilePath);
        }
        /// <summary>
        /// Upload a file on the GSS
        /// </summary>
        /// <param name="localFilePath">Local File path</param>
        /// <param name="cloudFilename">Cloud filename. For PLM: [folder]/[filename]</param>
        /// <param name="distantPath">path folder</param>
        /// <param name="compress">set true to compress the file</param>
        /// <returns></returns>
        public FileDescription UploadFile(string localFilePath, string cloudFilename, string distantPath, bool compress = true)
        {
            string serverFilename;

            if (compress)
            {
                localFilePath  = GenericFileStorage.ZipFile(localFilePath);
                cloudFilename += ".zip";
            }

            if (distantPath.StartsWith(this.FilePrefix))
            {
                distantPath = distantPath.Substring(FilePrefix.Length);
            }

            string cloudFolderEncoded   = distantPath == "" ? "" : System.Web.HttpUtility.UrlEncode(distantPath.Trim('/')) + "/";
            string cloudFilenameEncoded = System.Web.HttpUtility.UrlEncode(cloudFilename);

            serverFilename = this.FilePrefix + cloudFolderEncoded + cloudFilenameEncoded;

            this.DeleteFileIfExist(serverFilename);

            // Now we must ask GSS how to upload the file:
            // (this calls the service a second time)
            var resourceInfo = fileUtils.getResourceInformation(serverFilename, this.SessionToken);

            var createDescription = resourceInfo.createDescription;

            // Now we create
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(createDescription.url);

            // We set the parameters as described by the service
            request.Method = createDescription.httpMethod;
            request.Headers[createDescription.sessionTokenField] = this.SessionToken;
            request.Timeout   = System.Threading.Timeout.Infinite;
            request.KeepAlive = true;

            if (createDescription.headers != null)
            {
                foreach (var headerField in createDescription.headers)
                {
                    request.Headers[headerField.key] = headerField.value;
                }
            }

            //Write the localFile on the server
            using (BinaryWriter writer = new BinaryWriter(request.GetRequestStream()))
            {
                using (BinaryReader reader = new BinaryReader(System.IO.File.OpenRead(localFilePath), fileEncoding))
                {
                    int    bufferSize = this.BufferSize;
                    byte[] buffer     = new byte[bufferSize];
                    while ((buffer = reader.ReadBytes(bufferSize)).GetLength(0) > 0)
                    {
                        writer.Write(buffer);
                    }
                }
            }

            // In return we will get the id of the newly created file:
            try
            {
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                if (response.StatusCode != HttpStatusCode.OK && response.StatusCode != HttpStatusCode.Accepted && response.StatusCode != HttpStatusCode.Created)
                {
                    throw new Exception("Wrong status code returned");
                }

                string returnedID = "";
                using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                {
                    returnedID = reader.ReadToEnd().Trim();
                }

                if (string.IsNullOrEmpty(returnedID))
                {
                    returnedID = resourceInfo.uniqueName;
                }

                //var test = fileUtils.getResourceInformation(returnedID, this.SessionToken);

                return(new FileDescription(resourceInfo.visualName, resourceInfo.uniqueName, new FileIdentifier(returnedID), resourceInfo.type));
            }
            catch (WebException wex)
            {
                throw new Exception("Generic File Storage Exception", wex);
            }
        }