using Blog.Common.Utils;
using System;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using Blog.Common.Vo;
namespace Blog.Common.OSS.WestYun
{
    public class WestClient
    {
        private readonly int CHUNK_SIZE = 1024 * 1024;
        private string bucket { get; set; }
        private string userName { get; set; }
        private string password { get; set; }
        /// <summary>
        /// 设置文件内容的md5加密
        /// </summary>
        public string ContentMd5 { get; set; }
        /// <summary>
        /// 设置验证方式 false为基础认证，其他为签名认证
        /// </summary>
        public bool baseCheck = false;
        /// <summary>
        /// 是否异步执行，适用于删除和上传文件
        /// </summary>
        public bool Async { get; set; }
        /// <summary>
        /// 文件绝对地址
        /// </summary>
        private string url { get; set; }
        /// <summary>
        /// 上传方法
        /// </summary>
        public string method { get; set; }
        /// <summary>
        /// 上传时间
        /// </summary>
        private DateTime date { get; set; }
        /// <summary>
        /// 上传主机
        /// </summary>
        private readonly string host = "fss-my.vhostgo.com";

        public WestClient(string bucket, string userName, string password, bool baseCheck=false)
        {
            this.bucket = bucket;
            this.userName = userName;
            this.password = password;
            this.baseCheck = baseCheck;
        }


        /// <summary>
        /// 授权 签名上传
        /// </summary>
        /// <param name="method"></param>
        /// <param name="uri"></param>
        /// <returns></returns>
        /// <summary>
        /// 获取认证
        /// </summary>
        /// <returns></returns>
        public string GetAuthorization()
        {
            if (baseCheck)
            {
                return "Basic " + Convert.ToBase64String(new ASCIIEncoding().GetBytes(string.Format("{0}:{1}", userName, password)));
            }
            var urlAddress = new Uri(this.url);
            var saveUrl = urlAddress.AbsolutePath + urlAddress.Query;
            var data = string.Format("{0}&{1}&{2}", method, saveUrl, date.ToUniversalTime().ToString("R"));
            if (!string.IsNullOrEmpty(ContentMd5))
            {
                data += "&" + ContentMd5;
            }
            var pwd = Convert.ToBase64String(new ASCIIEncoding().GetBytes(password));
            var hmac = new HMACSHA1(Encoding.UTF8.GetBytes(pwd));
            byte[] buffer = Encoding.UTF8.GetBytes(data);
            var sign = Convert.ToBase64String(hmac.ComputeHash(buffer));
            return "WESTYUN " + userName + ':' + sign;
        }
    
        public  bool UploadFile(string path, byte[] putData)
        {
            try { 
            this.date = DateTime.Now;
            if (putData==null||putData.Length == 0)
            {
                return false;
            }
            this.url= string.Join("/", new string[] { "http:/",host,bucket,path});
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(this.url);
            string authorization = GetAuthorization();
            request.Method =this.method;
            request.Date = this.date;
            request.ContentLength = putData.Length;
            request.KeepAlive = false;
            request.ServicePoint.Expect100Continue = false;
            request.Headers.Add("x-west-overwrite", "true");
            request.Headers.Add("x-west-automkdir", "true");
            request.Headers.Add("Authorization", authorization);
            byte[] b = putData;
            using (Stream stream = request.GetRequestStream())
            {
                stream.Write(b, 0, b.Length);
            }
            HttpWebResponse response= (HttpWebResponse)request.GetResponse();
            var reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
            string ret = reader.ReadToEnd();
            if (request != null)
            {
                request.Abort();
            }
            if (ret.Contains("code"))
            {
                var rs = JsonUtil.parse<ResultVo>(ret);
                    if (rs.code == "200")
                        return true;
            }
            }catch(Exception e)
            {
                throw e;
            }
            return false;
        }
    }
}
