// Copyright (C) 2012 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.google.gerrit.server.plugins;

import com.google.common.base.Strings;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.extensions.registration.RegistrationHandle;
import com.google.gerrit.extensions.registration.ReloadableRegistrationHandle;
import com.google.gerrit.lifecycle.LifecycleManager;
import com.google.gerrit.server.PluginUser;
import com.google.inject.Injector;
import com.google.inject.Module;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import org.eclipse.jgit.internal.storage.file.FileSnapshot;

public abstract class Plugin {
  public enum ApiType {
    EXTENSION,
    PLUGIN,
    JS
  }

  /** Unique key that changes whenever a plugin reloads. */
  public static final class CacheKey {
    private final String name;

    CacheKey(String name) {
      this.name = name;
    }

    @Override
    public String toString() {
      int id = System.identityHashCode(this);
      return String.format("Plugin[%s@%x]", name, id);
    }
  }

  static ApiType getApiType(Manifest manifest) throws InvalidPluginException {
    Attributes main = manifest.getMainAttributes();
    String v = main.getValue("Gerrit-ApiType");
    if (Strings.isNullOrEmpty(v) || ApiType.EXTENSION.name().equalsIgnoreCase(v)) {
      return ApiType.EXTENSION;
    } else if (ApiType.PLUGIN.name().equalsIgnoreCase(v)) {
      return ApiType.PLUGIN;
    } else if (ApiType.JS.name().equalsIgnoreCase(v)) {
      return ApiType.JS;
    } else {
      throw new InvalidPluginException("Invalid Gerrit-ApiType: " + v);
    }
  }

  private final String name;
  private final Path srcFile;
  private final ApiType apiType;
  private final boolean disabled;
  private final CacheKey cacheKey;
  private final PluginUser pluginUser;
  private final FileSnapshot snapshot;
  private CleanupHandle cleanupHandle;

  protected LifecycleManager manager;

  protected List<ReloadableRegistrationHandle<?>> reloadableHandles;

  public Plugin(
      String name, Path srcPath, PluginUser pluginUser, FileSnapshot snapshot, ApiType apiType) {
    this.name = name;
    this.srcFile = srcPath;
    this.apiType = apiType;
    this.snapshot = snapshot;
    this.pluginUser = pluginUser;
    this.cacheKey = new Plugin.CacheKey(name);
    this.disabled = srcPath != null && srcPath.getFileName().toString().endsWith(".disabled");
  }

  public CleanupHandle getCleanupHandle() {
    return cleanupHandle;
  }

  public void setCleanupHandle(CleanupHandle cleanupHandle) {
    this.cleanupHandle = cleanupHandle;
  }

  PluginUser getPluginUser() {
    return pluginUser;
  }

  public Path getSrcFile() {
    return srcFile;
  }

  public String getName() {
    return name;
  }

  @Nullable
  public abstract String getVersion();

  public ApiType getApiType() {
    return apiType;
  }

  @Nullable
  public String getApiVersion() {
    return null;
  }

  public Plugin.CacheKey getCacheKey() {
    return cacheKey;
  }

  public boolean isDisabled() {
    return disabled;
  }

  protected abstract void start(PluginGuiceEnvironment env) throws Exception;

  protected abstract void stop(PluginGuiceEnvironment env);

  public abstract PluginContentScanner getContentScanner();

  public abstract Injector getSysInjector();

  @Nullable
  public abstract Injector getSshInjector();

  @Nullable
  public abstract Injector getHttpInjector();

  @Nullable
  public abstract Injector getApiInjector();

  public void add(RegistrationHandle handle) {
    if (manager != null) {
      if (handle instanceof ReloadableRegistrationHandle) {
        if (reloadableHandles == null) {
          reloadableHandles = new ArrayList<>();
        }
        reloadableHandles.add((ReloadableRegistrationHandle<?>) handle);
      }
      manager.add(handle);
    }
  }

  List<ReloadableRegistrationHandle<?>> getReloadableHandles() {
    if (reloadableHandles != null) {
      return reloadableHandles;
    }
    return Collections.emptyList();
  }

  @Override
  public String toString() {
    return "Plugin [" + name + "]";
  }

  protected abstract boolean canReload();

  boolean isModified(Path jar) {
    return snapshot.isModified(jar.toFile());
  }

  public Optional<Module> getApiModule() {
    return Optional.empty();
  }
}
