local mimetypes = require \'mimetypes\'
local openssl = require \'openssl\'
local pkey = openssl.pkey

local function getSerialNo(pubilcKeyPath)
  local tmp_file = io.open(pubilcKeyPath, \'r\')
  local content = tmp_file:read(\'a\')
  local x = openssl.x509.read(content)
  local serial_no = x:serial()
  return serial_no
end

local function signRSA(data, privageKeyPath)
  local tmp_file = io.open(privageKeyPath, \'r\')
  local tmp_pkey = openssl.pkey
  local tmp_evp_key = tmp_pkey.read(tmp_file:read("a"), true, \'pem\', \'rsa\')
  local tmp_signature = tmp_evp_key:sign(data, \'sha256\')
  tmp_file:close()
  return openssl.base64(tmp_signature, true)
end

local function getsha256(content)
  local md = openssl.digest.get(\'sha256\')
  local mdc = md:new()
  mdc:update(content)
  local sha256 = mdc:final(false)
  print(sha256, \'sha256\')
  return sha256
end

local function test()
  local pubilcKeyPath = \'apiclient_cert.pem\'
  local privageKeyPath = \'apiclient_key.pem\'
  local mchid = \'your_mchid\'

  local serial_no = getSerialNo(pubilcKeyPath)
  local timestamp = os.time()
  local nonce_str = \'AGEWGAEWGEWGEWEWEWAGEWRGHREYHTU\'
  local filename = \'th.jpg\'
  local tmp_file = io.open(\'your_jpgpath.jpg\', \'rb\')
  local fileBytes = tmp_file:read(\'a\')
  tmp_file:close()

  local fileSha256 = getsha256(fileBytes)

  local sb = \'POST\' .. \'\n\' ..
  \'/v3/merchant/media/upload\' .. \'\n\' ..
  timestamp .. \'\n\' ..
  nonce_str .. \'\n\' ..
  string.format([[{"filename":"%s","sha256":"%s"}]], filename, fileSha256) .. \'\n\'
  print(sb)
  local tmp_sign = signRSA(sb, privageKeyPath)
  print(tmp_sign)
  local authorization ="WECHATPAY2-SHA256-RSA2048 mchid=\"" .. mchid .. "\",nonce_str=\"" ..
  nonce_str .. "\",signature=\"" .. tmp_sign ..
  "\",timestamp=\"" .. timestamp .. "\",serial_no=\"" .. serial_no .. "\"";

  local url = \'https://api.mch.weixin.qq.com/v3/merchant/media/upload\'


  local meta = {
    filename = filename,
    sha256 = fileSha256
  }
  
  local boundaryStr = "--boundary-----------\r\n";
  local out = boundaryStr;
  out = out .. \'Content-Disposition: form-data; name="meta"\' .."\r\n";
  out = out .. \'Content-Type: application/json\' .. "\r\n";
  out = out .. "\r\n";
  out = out .. json.encode(meta) .. "\r\n";
  out = out .. boundaryStr;
  out = out .. \'Content-Disposition:form-data;name="file"; filename="\' .. filename .. \'"\' .. "\r\n";
  out = out .. \'Content-Type:\' .. mimetypes.guess(filename) .. \';\' .. "\r\n";
  out = out .. "\r\n";
  out = out .. fileBytes ..  "\r\n";
  out = out .. "--boundary-----------\r\n";

  local ok, res = webclient.post(url, out, {
    [[User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36]],
    [[Accept:application/json]],
    "Authorization:" .. authorization ,
    [[Content-Type:multipart/form-data;]],
  } )

  print(ok, res)
end
test()