package mage.util;

import org.apache.log4j.Logger;

import java.net.URL;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.util.jar.Attributes;
import java.util.jar.Manifest;

/**
 * @author JayDi85
 */
public class JarVersion {

    private static final Logger logger = Logger.getLogger(JarVersion.class);
    public static final String JAR_BUILD_TIME_FROM_CLASSES = "runtime";
    private static final String JAR_BUILD_TIME_ERROR = "n/a";

    public static String getBuildTime(Class clazz) {
        // build time info inserted by maven on jar build phase (see root pom.xml)
        String resultFormat = "uuuu-MM-dd HH:mm";
        String className = clazz.getSimpleName() + ".class";
        String classPath = clazz.getResource(className).toString();

        // https://stackoverflow.com/a/1273432/1276632
        String manifestPath;
        if (classPath.startsWith("jar")) {
            // jar source
            manifestPath = classPath.substring(0, classPath.lastIndexOf('!') + 1) + "/META-INF/MANIFEST.MF";
        } else {
            // dir source (e.g. IDE's debug)
            // it's can be generated by runtime, but need extra code and performance: https://stackoverflow.com/questions/34674073/how-to-generate-manifest-mf-file-during-compile-phase
            // manifestPath = classPath.substring(0, classPath.lastIndexOf("/" + className)) + "/META-INF/MANIFEST.MF";
            return JAR_BUILD_TIME_FROM_CLASSES;
        }

        try {
            Manifest manifest = new Manifest(new URL(manifestPath).openStream());
            Attributes attr = manifest.getMainAttributes();
            String buildTime = attr.getValue("Build-Time");
            // default maven format: yyyy-MM-dd'T'HH:mm:ss'Z' or see maven.build.timestamp.format in pom file
            DateTimeFormatter sourceFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss'Z'").withZone(ZoneOffset.UTC);
            TemporalAccessor ta = sourceFormatter.parse(buildTime);
            DateTimeFormatter resultFormatter = DateTimeFormatter.ofPattern(resultFormat).withZone(ZoneOffset.UTC);
            return resultFormatter.format(ta);
        } catch (Throwable e) {
            logger.error("Can't read build time in jar manifest for class " + clazz.getName() + " and path " + manifestPath, e);
            return JAR_BUILD_TIME_ERROR;
        }
    }

    public static boolean isBuildTimeOk(String buildTime) {
        return buildTime != null
                && !buildTime.isEmpty()
                && !buildTime.equals(JAR_BUILD_TIME_ERROR)
                && !buildTime.equals(JAR_BUILD_TIME_FROM_CLASSES);
    }
}
