package com.atlassian.maven.plugins.amps.osgi;

import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.atlassian.maven.plugins.amps.AbstractAmpsMojo;

import com.google.common.collect.ImmutableMap;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import org.jfrog.maven.annomojo.annotations.MojoGoal;
import org.jfrog.maven.annomojo.annotations.MojoParameter;

import aQute.lib.osgi.Constants;

import static com.atlassian.maven.plugins.amps.util.FileUtils.file;

@MojoGoal("generate-manifest")
public class GenerateManifestMojo extends AbstractAmpsMojo
{
    private static final String BUILD_DATE_ATTRIBUTE = "Atlassian-Build-Date";
    private static final String BUILD_SIGNATURE_ATTRIBUTE = "Atlassian-Build-Signature";
    
    /**
     * The BND instructions for the bundle.
     */
    @MojoParameter
    private Map<String, String> instructions = new HashMap<String, String>();

    public void execute() throws MojoExecutionException, MojoFailureException
    {
        final MavenProject project = getMavenContext().getProject();
        
        // The Build-Date manifest attribute is used by the Atlassian licensing framework to determine
        // chronological order of bundle versions.  Its value is in milliseconds since the epoch.
        final String buildDateStr = String.valueOf(new Date().getTime());
        final String buildHash = getBuildHash(buildDateStr);
        final Map<String, String> basicAttributes = ImmutableMap.of(BUILD_DATE_ATTRIBUTE, buildDateStr,
                                                                    BUILD_SIGNATURE_ATTRIBUTE, buildHash);
        
        if (!instructions.isEmpty())
        {
            getLog().info("Generating a manifest for this plugin");

            if (!instructions.containsKey(Constants.EXPORT_PACKAGE))
            {
                instructions.put(Constants.EXPORT_PACKAGE, "");
            }

            File metainfLib = file(project.getBuild().getOutputDirectory(), "META-INF", "lib");
            if (metainfLib.exists())
            {
                StringBuilder sb = new StringBuilder(".");
                for (File lib : metainfLib.listFiles())
                {
                    sb.append(",").append("META-INF/lib/" + lib.getName());
                }
                instructions.put(Constants.BUNDLE_CLASSPATH, sb.toString());
            }
            getMavenGoals().generateBundleManifest(instructions, basicAttributes);
        }
        else
        {
            if (OsgiHelper.isAtlassianPlugin(project))
            {
                getLog().warn("Atlassian plugin detected as the organisation name includes the string 'Atlassian'.  If " +
                              "this is meant for production, you should add bundle " +
                              "instructions specifically configuring what packages are imported and exported.  This " +
                              "helps catch manifest generation bugs during the build rather than upon install.  The " +
                              "bundle generation configuration can be specified " +
                              "via the <instructions> element in the maven-" + getPluginInformation().getId()+"-plugin configuration.  For example:\n" +
                              "    <configuration>\n" +
                              "        <Import-Package>\n" +
                              "            com.atlassian.myplugin*,\n" +
                              "            com.library.optional.*;resolution:=optional,\n" +
                              "            *\n" +
                              "        </Import-Package>\n" +
                              "    </configuration>\n\n" +
                              "See the Maven bundle plugin (which is used under the covers) for more info: " +
                              "http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html#ApacheFelixMavenBundlePlugin%28BND%29-Instructions");
            }
            else
            {
                getLog().info("No manifest instructions found, adding only non-OSGi manifest attributes");
            }
            getMavenGoals().generateMinimalManifest(basicAttributes);
        }
    }
    
    private String getBuildHash(String buildDateStr)
    {
        // The following logic must be kept in sync with PluginLicenseBuilder in the UPM licensing-lib
        String hashInput = buildDateStr + ":" +
                getMavenContext().getProject().getGroupId() + ":" +
                getMavenContext().getProject().getArtifactId();
        return DigestUtils.sha256Hex(hashInput);
    }
}

@@ -62,16 +62,80 @@
 o.File;%0A
+import java.text.DateFormat;%0Aimport java.text.SimpleDateFormat;%0A
 import j
@@ -149,16 +149,16 @@
 l.Date;%0A
-
 import j
@@ -309,60 +309,8 @@
 p;%0A%0A
-import org.apache.commons.codec.digest.DigestUtils;%0A
 impo
@@ -843,24 +843,29 @@
 uild-Date%22;%0A
+    %0A
     private 
@@ -881,70 +881,85 @@
 nal 
-String BUILD_SIGNATURE_ATTRIBUTE = %22Atlassian-Build-Signature%22
+DateFormat BUILD_DATE_FORMAT = new SimpleDateFormat(%22yyyy-MM-dd'T'HH:mm:ssZ%22)
 ;%0A  
@@ -1296,16 +1296,26 @@
  // The 
+Atlassian-
 Build-Da
@@ -1448,55 +1448,8 @@
 ons.
-  Its value is in milliseconds since the epoch.
 %0A   
@@ -1500,89 +1500,44 @@
 eOf(
-new Date().getTime());%0A        final String buildHash = getBuildHash(build
+BUILD_DATE_FORMAT.format(new 
 Date
-Str
+())
 );%0A 
@@ -1641,114 +1641,8 @@
 eStr
-,%0A                                                                    BUILD_SIGNATURE_ATTRIBUTE, buildHash
 );%0A 
@@ -4241,408 +4241,6 @@
   %7D%0A
-    %0A    private String getBuildHash(String buildDateStr)%0A    %7B%0A        // The following logic must be kept in sync with PluginLicenseBuilder in the UPM licensing-lib%0A        String hashInput = buildDateStr + %22:%22 +%0A                getMavenContext().getProject().getGroupId() + %22:%22 +%0A                getMavenContext().getProject().getArtifactId();%0A        return DigestUtils.sha256Hex(hashInput);%0A    %7D%0A
 %7D%0A

change build date to human-readable format and remove hash signature