// Copyright (C) 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.googlesource.gerrit.plugins.manager.repository;

import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import com.google.gerrit.common.Version;
import com.google.gerrit.server.config.SitePaths;
import com.google.inject.Inject;

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

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;
import java.util.jar.Manifest;

public class CorePluginsRepository implements PluginsRepository {
  private static final Logger log = LoggerFactory
      .getLogger(CorePluginsRepository.class);
  private static final String GERRIT_VERSION = Version.getVersion();
  private final SitePaths site;

  @Inject
  public CorePluginsRepository(SitePaths site) {
    this.site = site;
  }

  static class SelectPluginsFromJar implements Predicate<JarEntry> {
    @Override
    public boolean apply(JarEntry entry) {
      String entryName = entry.getName();
      return (entryName.startsWith("WEB-INF/plugins") &&
              entryName.endsWith(".jar"));
    }
  }

  static class ExtractPluginInfoFromJarEntry implements
      Function<JarEntry, PluginInfo> {
    private String gerritWarFilename;

    public ExtractPluginInfoFromJarEntry(String gerritWarFilename) {
      this.gerritWarFilename = gerritWarFilename;
    }

    @Override
    public PluginInfo apply(JarEntry entry) {
      try {
        Path entryName = Paths.get(entry.getName());
        URI pluginUrl =
            new URI("jar:file:" + gerritWarFilename + "!/" + entry.getName());
        try (JarInputStream pluginJar =
            new JarInputStream(pluginUrl.toURL().openStream())) {
          Manifest manifestJarEntry = getManifestEntry(pluginJar);
          if (manifestJarEntry != null) {
            Attributes pluginAttributes = manifestJarEntry.getMainAttributes();
            return new PluginInfo(
                pluginAttributes.getValue("Gerrit-PluginName"),
                pluginAttributes.getValue("Implementation-Version"), "",
                pluginUrl.toString());
          }
          return new PluginInfo(entryName.getFileName().toString(), "", "",
              pluginUrl.toString());
        } catch (IOException e) {
          log.error("Unable to open plugin " + pluginUrl, e);
          return null;
        }
      } catch (URISyntaxException e) {
        log.error("Invalid plugin filename", e);
        return null;
      }
    }

    private Manifest getManifestEntry(JarInputStream pluginJar)
        throws IOException {
      for (JarEntry entry = pluginJar.getNextJarEntry(); entry != null; entry =
          pluginJar.getNextJarEntry()) {
        if (entry.getName().equals("META-INF/MANIFEST.MF")) {
          return new Manifest(pluginJar);
        }
      }
      return null;
    }
  }

  @Override
  public Collection<PluginInfo> list(String gerritVersion) throws IOException {
    if (!gerritVersion.equals(GERRIT_VERSION)) {
      log.warn(
          "No core plugins available for version {} which is different than " +
          "the current running Gerrit", gerritVersion);
      return Collections.emptyList();
    }

    final Path gerritWarPath = site.gerrit_war;
    if (gerritWarPath == null) {
      log.warn("Core plugins not available on non-war Gerrit distributions");
      return Collections.emptyList();
    }

    try (JarFile gerritWar = new JarFile(gerritWarPath.toFile())) {

      return FluentIterable
          .from(Collections.list(gerritWar.entries()))
          .filter(new SelectPluginsFromJar())
          .transform(
              new ExtractPluginInfoFromJarEntry(gerritWarPath.toString()))
          .filter(new Predicate<PluginInfo>() {
            @Override
            public boolean apply(PluginInfo pluginInfo) {
              return pluginInfo != null;
            }
          }).toSortedList(new Comparator<PluginInfo>() {
            @Override
            public int compare(PluginInfo a, PluginInfo b) {
              return a.name.compareTo(b.name);
            }
          });
    }
  }
}
