// 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());
          } else {
            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);
            }
          });
    }
  }
}
