package de.ivu.elect.business.system.entity;

import de.ivu.elect.business.system.control.ElectDbInitializer;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;

public class DbScript implements Serializable, Comparable<DbScript> {

  private static final Logger LOG = LoggerFactory.getLogger(DbScript.class);
  public static final String CREATE_SCRIPT = "elect-create-all";
  public static final String VERSION_MARKER = "_v";

  private final String name;
  private final Long vonVersion;
  private final Long nachVersion;
  private final DbScriptType type;

  public DbScript(String scriptName) {
    vonVersion = parseVonVersion(scriptName);
    nachVersion = parseNachVersion(scriptName);
    type = parseType(vonVersion, nachVersion, scriptName);
    if (scriptName == null) {
      name = "";
    } else {
      name = scriptName;
    }
  }

  public String getName() {
    return name;
  }

  static DbScriptType parseType(Long vonVersion, Long nachVersion, String scriptName) {
    if (vonVersion != null) {
      if (nachVersion != null) {
        return DbScriptType.UPDATE;
      }
      if (scriptName.startsWith(CREATE_SCRIPT)) {
        return DbScriptType.CREATE;
      }
      return DbScriptType.KORREKTURDATEN;
    }
    return DbScriptType.UNBEKANNT;
  }

  static Long parseNachVersion(String scriptName) {
    if (StringUtils.isBlank(scriptName)) {
      return null;
    }
    try {

      int startTag = scriptName.toLowerCase().indexOf("_nach_");
      if (startTag > -1) {
        return Long.parseLong(scriptName.substring(startTag + 6, startTag + 9));
      }
    } catch (Exception e) {

      LOG.warn("Script Versionsnummer(nach) kann nicht geparst werden: '" + scriptName + "', " + e.getMessage());
    }
    return null;

  }

  static Long parseVonVersion(String scriptName) {
    if (StringUtils.isBlank(scriptName)) {
      return null;
    }
    try {

      int startTag = scriptName.toLowerCase().indexOf(VERSION_MARKER);
      if (startTag > -1) {
        return Long.parseLong(scriptName.substring(startTag + VERSION_MARKER.length(), startTag + VERSION_MARKER.length() + 3));
      }
    } catch (Exception e) {

      LOG.warn("Script Versionsnummer(von) kann nicht geparst werden: '" + scriptName + "', " + e.getMessage());
    }
    return null;

  }

  public Long getVonVersion() {
    return vonVersion;
  }

  public Long getNachVersion() {
    return nachVersion;
  }

  public DbScriptType getType() {
    return type;
  }

  @Override
  public int compareTo(DbScript other) {
    if (this.getVonVersion() == null) {
      if (other.getVonVersion() == null) {
        return this.getName().compareTo(other.getName());
      }
      return -1;
    }

    if (other.getVonVersion() == null) {
      return 1;
    }

    int result = this.getVonVersion().compareTo(other.getVonVersion());
    if (result != 0) {
      return result;
    }

    if (this.getNachVersion() == null) {
      if (other.getNachVersion() == null) {
        return this.getName().compareTo(other.getName());
      }
      return -1;
    }

    if (other.getNachVersion() == null) {
      return 1;
    }

    return this.getName().compareTo(other.getName());
  }

  @Override
  public String toString() {
    return "DbScript{" +
            "name='" + name + '\'' +
            ", vonVersion=" + vonVersion +
            ", nachVersion=" + nachVersion +
            ", type=" + type +
            '}';
  }
}
