/*
 * Copyright (c) 2014 Spotify AB
 */

package com.spotify.apollo.meta;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
import java.util.Properties;
import java.util.jar.Attributes;
import java.util.jar.Manifest;

public class MetaDescriptor {

  private static final Logger LOG = LoggerFactory.getLogger(MetaDescriptor.class);

  private static final String APOLLO_VERSION = "X-Spotify-Apollo-Version";
  private static final String IMPL_VERSION = "Implementation-Version";

  private final Descriptor descriptor;
  private final String apolloVersion;

  MetaDescriptor(Descriptor descriptor, String apolloVersion) {
    this.descriptor = descriptor;
    this.apolloVersion = apolloVersion;
  }

  public Descriptor descriptor() {
    return descriptor;
  }

  public String apolloVersion() {
    return apolloVersion;
  }

  // TODO: load real artifact and group id
  // TODO: can apollo version be loaded more reliably?
  public static MetaDescriptor readMetaDescriptor(String serviceName, ClassLoader classLoader)
      throws IOException {
    String apolloVersion;
    String version;

    try {
      apolloVersion = loadApolloVersion(classLoader);
    } catch (IOException e) {
      apolloVersion = "0.0.0-UNKNOWN";
    }

    final Manifest manifest = getManifest(classLoader);

    if (manifest != null) {
      final Attributes attributes = manifest.getMainAttributes();
      version = attributes.getValue(IMPL_VERSION);
    } else {
      LOG.warn("Could not find manifest, continuing with default artifact metadata");
      version = "0.0.0-UNKNOWN";
    }

    return new MetaDescriptor(
        Descriptor.create(serviceName, version),
        apolloVersion);
  }

  protected static String loadApolloVersion(ClassLoader classLoader) throws IOException {
    Properties properties = new Properties();
    properties.load(classLoader.getResourceAsStream("metaDescriptor.properties"));
    return properties.getProperty("apolloVersion");
  }

  private static Manifest getManifest(ClassLoader classLoader) throws IOException {
    try {
      Enumeration<URL> resources = classLoader.getResources("META-INF/MANIFEST.MF");

      while (resources.hasMoreElements()) {
        final URL url = resources.nextElement();
        final Manifest manifest = new Manifest(url.openStream());
        final Attributes mainAttributes = manifest.getMainAttributes();
        final String value = mainAttributes.getValue(APOLLO_VERSION);
        if (value != null) {
          return manifest;
        }
      }
    } catch (IOException e) {
      LOG.error("Failed to read manifest", e);
      throw new IOException("Failed to find manifest", e);
    }

    return null;
  }
}

@@ -1325,157 +1325,33 @@
     
-final Manifest manifest = getManifest(classLoader);%0A%0A    if (manifest != null) %7B%0A      final Attributes attributes = manifest.getMainAttributes
+version = loadVersion
 ();%0A
-  
     
@@ -1364,147 +1364,25 @@
 n = 
-attributes.getValue(IMPL_VERSION);%0A    %7D else %7B%0A      LOG.warn(%22Could not find manifest, continuing with default artifact metadata%22);%0A     
+version != null ?
  ver
@@ -1382,25 +1382,25 @@
 l ? version 
-=
+:
  %220.0.0-UNKN
@@ -1400,30 +1400,24 @@
 .0-UNKNOWN%22;
-%0A    %7D
 %0A%0A    return
@@ -1799,232 +1799,50 @@
   pr
-ivate static Manifest getManifest(ClassLoader classLoader) throws IOException %7B%0A    try %7B%0A      Enumeration%3CURL%3E resources = classLoader.getResources(%22META-INF/MANIFEST.MF%22);%0A%0A      while (resources.hasMoreElements()
+otected static String loadVersion(
 ) %7B%0A    
     
@@ -1841,493 +1841,75 @@
     
-   
- final URL url = resources.nextElement();%0A        final Manifest manifest = new Manifest(url.openStream());%0A        final Attributes mainAttributes = manifest.getMainAttributes();%0A        final String value = mainAttributes.getValue(APOLLO_VERSION);%0A        if (value != null) %7B%0A          return manifest;%0A        %7D%0A      %7D%0A    %7D catch (IOException e) %7B%0A      LOG.error(%22Failed to read manifest%22, e);%0A      throw new IOException(%22Failed to find manifest%22, e);%0A    %7D%0A%0A    return null
+return MetaDescriptor.class.getPackage().getImplementationVersion()
 ;%0A  

Load version using .getImplementationVersion()