#include "updatebyme.h"
#include "SDmanger.h"
void UpDateClassByme::performUpdate(Stream &updateSource, size_t updateSize)
{
    if (Update.begin(updateSize))
    {
        Serial.println("Writes : ");
        size_t written = Update.writeStream(updateSource);
        if (written == updateSize)
        {
            Serial.println("Writes : " + String(written) + " successfully");
        }
        else
        {
            Serial.println("Written only : " + String(written) + "/" + String(updateSize) + ". Retry?");
        }
        if (Update.end())
        {
            Serial.println("OTA finished!");
            if (Update.isFinished())
            {
                Serial.println("Restart ESP device!");
                abort();
            }
            else
            {
                Serial.println("OTA not fiished");
            }
        }
        else
        {
            Serial.println("Error occured #: " + String(Update.getError()));
        }
    }
    else
    {
        Serial.println("Cannot beggin update");
    }
}


size_t UpDateClassByme::DownloadFirmwareForurl(String version)
{
    String url="/weather/firmware/esp32/firmware_"+version+".bin";
    int err = http->get(url.c_str());
    if (err != 0)
    {
        Serial.println(F("Date failed to connect"));
        vTaskDelay(10000);
        return 0;
    }
    int status = http->responseStatusCode();
    if (!status)
    {
        vTaskDelay(10000);
        return 0;
    }
    Serial.print(F("Response status code: "));
    Serial.println(status);
    //  SerialMon.println(F("Response Headers:"));
    size_t count=0;
    while (http->headerAvailable())
    {
        String headerName = http->readHeaderName();
        String headerValue = http->readHeaderValue();
         Serial.println("Date:    " + headerName + " : " + headerValue);
        if (headerName=="Content-Length")
        {
            count=headerValue.toInt();
            /* code */
        }
        

    }
     Serial.println("lenth is "+String(count));
    if (http->isResponseChunked())
    {
        Serial.println(F("Date The response is chunked"));
    }
    char *str=new char[1000];
    int lent=count/1000;
    File file;

    file = SD_MMC.open("/update.bin", "wb");
    
    for (size_t i = 0; i < lent; i++)
    {
            http->readBytes(str,1000);
            file.write((const byte *)str,1000);
            Serial.print("download ");
            Serial.println(String(i*100/lent));
        /* code */
    }
     http->readBytes(str,count%1000);
      file.write((const byte *)str,count%1000);
    file.flush();
      file.close();
    //performUpdate(*http,cout);

 
  //  http->readBytes
     Serial.println("adfasdfsadfsdfsd");
     //Serial.write(str,cout);
    //Serial.println(body.length());
    http->stop();
    return count;
   // return body;
}

void UpDateClassByme::initme(String Version)
{
    CurrentVersion=Version;
    
}
void UpDateClassByme::updateversion()
{
     String Targetversion=GetValueFromNet("/weather/php/upVserion.php",StationID+":"+CurrentVersion);
}
bool UpDateClassByme::CheckAndUpdate()
{
    
 
    String Targetversion=GetValueFromNet("/weather/php/GetVserion.php",StationID);
    if ( Targetversion=="0"||Targetversion==CurrentVersion||Targetversion=="")
    {
        return true;
      
    }
    Serial.println("targetvesion is:"+Targetversion);
     
   //size_t countdownload1=375584;
    size_t countdownload1=DownloadFirmwareForurl(Targetversion);
   if (countdownload1<10000)
    {
        return false;
    }
     Serial.println("count download is:"+String(countdownload1));

    String MD5=GetValueFromNet("/weather/php/GetMD5Value.php",Targetversion);
       
    if (MD5=="0")
    {
        return false;
       
    } 
    
   // updater.setMD5(MD5);
    MD5Builder md5my;
    

    File file;

    file = SD_MMC.open("/update.bin", "rb");
    md5my.begin();
    md5my.addStream(file,countdownload1);
    md5my.calculate();
    String md5com=md5my.toString();
    Serial.println("md5 comput is:"+md5my.toString());
   Serial.println("md5 should is:"+MD5);
   file.close();
  if (MD5==md5com)
  {
    file = SD_MMC.open("/update.bin", "rb");
    performUpdate(file,countdownload1);
    return true;
    /* code */
  }
  



   return true;







}









UpDateClassByme::UpDateClassByme(HttpClient *httptm)
{
    http=httptm;
    StationID="000";
}
String UpDateClassByme::GetValueFromNet(String url,String Key)
{
   
    http->beginRequest();
    http->post(url.c_str());

   
    http->sendHeader(HTTP_HEADER_CONTENT_LENGTH, Key.length());
    http->endRequest();
    int err = http->write((const byte *)Key.c_str(), Key.length());
     Serial.print("send date size");
     Serial.println(err);

    if (err == 0)
    {

        http->stop();
        return "-1";
    }
    int status = http->responseStatusCode();
    if (!status)
    {
        http->stop();
     return "-1";
    }

    int length = http->contentLength();
    if (length == 0)
    {
        http->stop();
     return "-1";
    }

    String body = http->responseBody();
    Serial.println("body:"+body);

    http->stop();
    return body;
}
