/**
 * Copyright (c) 2015 Takari, Inc.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 */
package io.takari.maven.plugins;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;

import org.apache.maven.Maven;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Mojo(name = "update-check")
public class UpdateCheckMojo extends AbstractMojo {

  private final Logger log = LoggerFactory.getLogger(getClass());

  public static final String REMOTE_URL = "https://download.takari.io/latest/takari-lifecycle";

  public static final String GROUP_ID = "io.takari.maven.plugins";
  public static final String ARTIFACT_ID = "takari-lifecycle-plugin";

  public static final long ONE_WEEK_MS = TimeUnit.DAYS.toMillis(7);

  public static final String UPDATE_CHECK_TIMESTAMP_PREF = "updateCheckTimestamp";

  @Override
  public void execute() throws MojoExecutionException, MojoFailureException {

    try {
      String version = getLocalVersion(getClass().getClassLoader(), GROUP_ID, ARTIFACT_ID);
      if (version == null) {
        log.debug("Could not determine {}:{} version, skipping update check", GROUP_ID, ARTIFACT_ID);
        return; // TODO generate maven pom.properties inside m2e
      }

      Preferences preferences = Preferences.userRoot().node(GROUP_ID.replace('.', '/')).node(ARTIFACT_ID).node(version.toString());
      final long timestamp = System.currentTimeMillis();
      if (timestamp - preferences.getLong(UPDATE_CHECK_TIMESTAMP_PREF, 0) < ONE_WEEK_MS) {
        // only check for update once a week
        return;
      }

      preferences.putLong(UPDATE_CHECK_TIMESTAMP_PREF, timestamp);
      preferences.flush();

      String mavenVersion = getLocalVersion(Maven.class.getClassLoader(), "org.apache.maven", "maven-core");
      String javaVersion = System.getProperty("java.version");

      // doing url encoding correctly is apparently hard in java https://github.com/google/guava/issues/1756
      String query = String.format("m=%s&j=%s", mavenVersion, javaVersion);
      URLConnection conn = new URL(REMOTE_URL + "?" + query).openConnection();
      conn.addRequestProperty("User-Agent", "takari-lifecycle/" + version.toString());

      try (InputStream is = conn.getInputStream()) {
        String latestVersion = getVersion(is);
        if (latestVersion != null && new DefaultArtifactVersion(version).compareTo(new DefaultArtifactVersion(latestVersion)) < 0) {
          log.warn("Takari Lifecycle version {} is outdated, consider upgrade to {}", version, latestVersion);
        }
      }
    } catch (IOException | BackingStoreException ignored) {
      // this is a just courtesy to the user, no need to break the build
    }
  }

  private String getLocalVersion(ClassLoader loader, String groupId, String artifactId) throws IOException {
    String path = "META-INF/maven/" + groupId + "/" + artifactId + "/pom.properties";
    try (InputStream is = loader.getResourceAsStream(path)) {
      return is != null ? getVersion(is) : null;
    }
  }

  private String getVersion(InputStream is) throws IOException {
    Properties p = new Properties();
    p.load(is);
    return p.getProperty("version");
  }

}

@@ -1471,16 +1471,84 @@
 tamp%22;%0A%0A
+  public static final int UPDATE_TIMEOUT_MS = 30000; // 30 seconds%0A%0A
   @Overr
@@ -2901,24 +2901,119 @@
 toString());
+%0A      conn.setConnectTimeout(UPDATE_TIMEOUT_MS);%0A      conn.setReadTimeout(UPDATE_TIMEOUT_MS);
 %0A%0A      try 

set connect and read timeout when checking for updates