
bool setConfig(char* param, char* value) {
  // sets the corresponding config variable for 'param' to new value
  // does not trigger saving to flash
  // does not distinguish between config and config2 as this is only split on flash and web-interface

  Serial.print("setConfig - '");
  Serial.print(param);
  Serial.print("' to '");
  Serial.print(value);
  Serial.println("'");

  //confdata
  if ( strcmp(param, "devName") == 0 ) {
    strlcpy(deviceName, value, 31);
  }
  else if ( strcmp(param, "apiToken") == 0 ) {
    strlcpy(http_token, value, 31);
  }
  else if ( strcmp(param, "httpUA") == 0 ) {
    strlcpy(http_user, value, 31);
  }
  else if ( strcmp(param, "httpPA") == 0 ) {
    strlcpy(http_pass, value, 31);
  }
  else if ( strcmp(param, "httpAuth") == 0 ) {
    if (atoi(value) == 1) http_user_auth = true;
    else http_user_auth = false;
  }
  else if ( strcmp(param, "httpU1") == 0 ) {
    strlcpy(http_user1, value, 31);
  }
  else if ( strcmp(param, "httpP1") == 0 ) {
    strlcpy(http_pass1, value, 31);
  }
  else if ( strcmp(param, "httpU2") == 0 ) {
    strlcpy(http_user2, value, 31);
  }
  else if ( strcmp(param, "httpP2") == 0 ) {
    strlcpy(http_pass2, value, 31);
  }
  else if ( strcmp(param, "mqttHost") == 0 ) {
    strlcpy(mqtt_server, value, 41);
    //mqtt_server[40] = '\0';
  }
  else if ( strcmp(param, "mqttPort") == 0 ) {
    mqtt_port = atoi(value);
  }
  else if ( strcmp(param, "mqttUser") == 0 ) {
    strlcpy(mqtt_user, value, 31);
  }
  else if ( strcmp(param, "mqttPass") == 0 ) {
    strlcpy(mqtt_pass, value, 31);
  }
  else if ( strcmp(param, "inTop") == 0 ) {
    strlcpy(mqtt_topic_in, value, 51);
  }
  else if ( strcmp(param, "outTop") == 0 ) {
    strlcpy(mqtt_topic_out, value, 51);
  }
  else if ( strcmp(param, "outRet") == 0 ) {
    //Serial.print("outRet DEBG: '"); Serial.print(value); Serial.print("' -> ");
    if (atoi(value) == 1) mqtt_outRetain = true;
    else mqtt_outRetain = false;
    //Serial.println(mqtt_outRetain);
  }
  else if ( strcmp(param, "willTop") == 0 ) {
    strlcpy(mqtt_willTopic, value, 51);
  }
  else if ( strcmp(param, "willQos") == 0 ) {
    int tmpval = atoi(value);
    if (tmpval >= 0 && tmpval <= 2) mqtt_willQos = tmpval;
  }
  else if ( strcmp(param, "willRet") == 0 ) {
    if (atoi(value) == 1) mqtt_willRetain = true;
    else mqtt_willRetain = false;
  }
  else if ( strcmp(param, "willMsg") == 0 ) {
    strlcpy(mqtt_willMsg, value, 31);
  }
  else if ( strcmp(param, "connMsg") == 0 ) {
    strlcpy(mqtt_connMsg, value, 31);
  }
}

void printConfigWeb() {
  // prints current config vars to serial
  Serial.println("\nconfDataWeb:");
  Serial.print("devName: ");
  Serial.println(deviceName);
  Serial.print("apiToken: ");
  Serial.println(http_token);
  Serial.print("httpUA: ");
  Serial.println(http_user);
  Serial.print("httpPA: ");
  Serial.println(http_pass);
  Serial.print("httpAuth: ");
  Serial.println(http_user_auth);
  Serial.print("httpU1: ");
  Serial.println(http_user1);
  Serial.print("httpP1: ");
  Serial.println(http_pass1);
  Serial.print("httpU2: ");
  Serial.println(http_user2);
  Serial.print("httpP2: ");
  Serial.println(http_pass2);
}

void printConfigMqtt() {
  // prints current config vars to serial
  Serial.println("\nconfDataMqtt:");
  Serial.print("mqttHost: ");
  Serial.println(mqtt_server);
  Serial.print("mqttPort: ");
  Serial.println(mqtt_port);
  Serial.print("mqttUser: ");
  Serial.println(mqtt_user);
  Serial.print("mqttPass: ");
  Serial.println(mqtt_pass);
  Serial.print("inTop: ");
  Serial.println(mqtt_topic_in);
  Serial.print("outTop: ");
  Serial.println(mqtt_topic_out);
  Serial.print("outRet: ");
  Serial.println(mqtt_outRetain);
  Serial.print("willTop: ");
  Serial.println(mqtt_willTopic);
  Serial.print("willQos: ");
  Serial.println(mqtt_willQos);
  Serial.print("willRet: ");
  Serial.println(mqtt_willRetain);
  Serial.print("willMsg: ");
  Serial.println(mqtt_willMsg);
  Serial.print("connMsg: ");
  Serial.println(mqtt_connMsg);
}

bool loadConfigWeb() { // loadConfigWeb
  if (SPIFFS.exists("/confWeb.json")) {
    File configFile = SPIFFS.open("/confWeb.json", "r");
    if (!configFile) {
      Serial.println("ERR: Failed to open file /confWeb.json");
      return false;
    }
    else {
      Serial.println("file /confWeb.json opened");
      size_t size = configFile.size();

      Serial.print("file size: ");
      Serial.println(size);

      //      Serial.println("file content:");
      //
      //      while (configFile.available()) {
      //        //Lets read line by line from the file
      //        String line = configFile.readStringUntil('\n');
      //        Serial.println(line);
      //      }
      //      Serial.println();

      if (size > 1000) {
        Serial.println("Config file size is too large");
        return false;
      }

      Serial.println("allocate buffer");
      // Allocate a buffer to store contents of the file.
      std::unique_ptr<char[]> buf(new char[size]);

      Serial.println("read file bytes to buffer");
      // We don't use String here because ArduinoJson library requires the input
      // buffer to be mutable. If you don't use ArduinoJson, you may as well
      // use configFile.readString instead.
      configFile.readBytes(buf.get(), size);

      StaticJsonBuffer<1050> jsonBuffer;
      JsonObject& json = jsonBuffer.parseObject(buf.get());

      if (!json.success()) {
        Serial.println("Failed to parse config file");
        return false;
      }

      strlcpy(deviceName, json["devName"] | "", 31);
      strlcpy(http_token, json["apiToken"] | "", 31);
      strlcpy(http_user, json["httpUA"] | "", 31);
      strlcpy(http_pass, json["httpPA"] | "", 31);

      if (atoi(json["httpAuth"] | "0") == 1) http_user_auth = true;
      else http_user_auth = false;
      
      strlcpy(http_user1, json["httpU1"] | "", 31);
      strlcpy(http_pass1, json["httpP1"] | "", 31);
      strlcpy(http_user2, json["httpU2"] | "", 31);
      strlcpy(http_pass2, json["httpP2"] | "", 31);
      
      Serial.println("Loaded config values:");
      printConfigWeb();
      return true;
    }
    configFile.close();
  }
  else {
    Serial.println("file /confWeb.json file does not exist");
    return false;
  }


} // loadConfigWeb



bool loadConfigMqtt() { // loadConfigMqtt
  if (SPIFFS.exists("/confMqtt.json")) {
    File configFile = SPIFFS.open("/confMqtt.json", "r");
    if (!configFile) {
      Serial.println("ERR: Failed to open file /confMqtt.json");
      return false;
    }
    else {
      Serial.println("file /confMqtt.json opened");
      size_t size = configFile.size();

      Serial.print("file size: ");
      Serial.println(size);

      //      Serial.println("file content:");
      //
      //      while (configFile.available()) {
      //        //Lets read line by line from the file
      //        String line = configFile.readStringUntil('\n');
      //        Serial.println(line);
      //      }
      //      Serial.println();

      if (size > 1000) {
        Serial.println("Config file size is too large");
        return false;
      }

      Serial.println("allocate buffer");
      // Allocate a buffer to store contents of the file.
      std::unique_ptr<char[]> buf(new char[size]);

      Serial.println("read file bytes to buffer");
      // We don't use String here because ArduinoJson library requires the input
      // buffer to be mutable. If you don't use ArduinoJson, you may as well
      // use configFile.readString instead.
      configFile.readBytes(buf.get(), size);

      StaticJsonBuffer<1050> jsonBuffer;
      JsonObject& json = jsonBuffer.parseObject(buf.get());

      if (!json.success()) {
        Serial.println("Failed to parse config file");
        return false;
      }
      
      strlcpy(mqtt_server, json["mqttHost"] | "", 41);
      mqtt_port = atoi(json["mqttPort"] | "1883");
      strlcpy(mqtt_user, json["mqttUser"] | "", 31);
      strlcpy(mqtt_pass, json["mqttPass"] | "", 31);
      strlcpy(mqtt_topic_in, json["inTop"] | "", 51);
      strlcpy(mqtt_topic_out, json["outTop"] | "", 51);

      //char outrettmp[8];
      //strcpy(outrettmp, json["outRet"]);
      //Serial.print("outRet='"); Serial.print(outrettmp); Serial.print("', atoi(outRet)='"); Serial.print(atoi(outrettmp));Serial.println("'");
      if (atoi(json["outRet"] | "0") == 1) mqtt_outRetain = true;
      else mqtt_outRetain = false;

      strlcpy(mqtt_willTopic, json["willTop"] | "", 51);
      mqtt_willQos = atoi(json["willQos"] | "0");

      if (atoi(json["willRet"] | "0") == 1) mqtt_willRetain = true;
      else mqtt_willRetain = false;

      strlcpy(mqtt_willMsg, json["willMsg"] | "", 31);
      strlcpy(mqtt_connMsg, json["connMsg"] | "", 31);

      Serial.println("Loaded config values:");
      printConfigMqtt();
      return true;
    }
    configFile.close();
  }
  else {
    Serial.println("file /confMqtt.json file does not exist");
    return false;
  }
} // loadConfigMqtt


bool saveConfigWeb() { // safeConfig
  StaticJsonBuffer<1050> jsonBuffer;
  JsonObject& json = jsonBuffer.createObject();

  json["devName"] = deviceName;
  json["apiToken"] = http_token;
  json["httpUA"] = http_user;
  json["httpPA"] = http_pass;
  
  if(http_user_auth) json["httpAuth"] = 1;
  else json["httpAuth"] = 0;
  
  json["httpU1"] = http_user1;
  json["httpP1"] = http_pass1;
  json["httpU2"] = http_user2;
  json["httpP2"] = http_pass2;

  yield();

  File configFile = SPIFFS.open("/confWeb.json", "w");
  if (!configFile) {
    Serial.println("Failed to open file confWeb.json for writing");
    return false;
  }

  json.printTo(configFile);
  return true;
} // safeConfig

bool saveConfigMqtt() { // safeConfig
  StaticJsonBuffer<1050> jsonBuffer;
  JsonObject& json = jsonBuffer.createObject();
  json["mqttHost"] = mqtt_server;
  json["mqttPort"] = mqtt_port;
  json["mqttUser"] = mqtt_user;
  json["mqttPass"] = mqtt_pass;
  json["inTop"] = mqtt_topic_in;
  json["outTop"] = mqtt_topic_out;

  if(mqtt_outRetain) json["outRet"] = 1;
  else json["outRet"] = 0;
  
  json["willTop"] = mqtt_willTopic;
  json["willQos"] = mqtt_willQos;
  
  if(mqtt_willRetain) json["willRet"] = 1;
  else json["willRet"] = 0;
  
  json["willMsg"] = mqtt_willMsg;
  json["connMsg"] = mqtt_connMsg;

  yield();

  File configFile = SPIFFS.open("/confMqtt.json", "w");
  if (!configFile) {
    Serial.println("Failed to open file confMqtt.json for writing");
    return false;
  }

  json.printTo(configFile);
  return true;
} // safeConfig


void checkSaveConfigTriggered() {
  if (saveConfigWebToFlash) {
    saveConfigWebToFlash = false;
    saveConfigWeb();
  }
  if (saveConfigMqttToFlash) {
    saveConfigMqttToFlash = false;
    saveConfigMqtt();
  }
  //  if (saveConfigHwToFlash) {
  //    saveConfigHwToFlash = false;
  //    saveConfigHw();
  //  }
}

void deleteConfig() {
  Serial.println("deleting configuration");
  if (SPIFFS.remove("/formatComplete.txt")) {
    Serial.println("config will be deleted after reboot");
    delay(100);
    ESP.restart();
  }
}
