// Copyright (C) 2014 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.scripting.groovyprovider;

import com.google.common.base.Optional;
import com.google.common.collect.Sets;
import com.google.gerrit.server.plugins.AbstractPreloadedPluginScanner;
import com.google.gerrit.server.plugins.InvalidPluginException;
import com.google.gerrit.server.plugins.PluginEntry;
import com.google.gerrit.server.plugins.Plugin.ApiType;

import groovy.lang.Binding;
import groovy.lang.Script;
import groovy.util.ResourceException;
import groovy.util.ScriptException;

import org.codehaus.groovy.runtime.InvokerHelper;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Set;

public class GroovyPluginScanner extends AbstractPreloadedPluginScanner {

  public GroovyPluginScanner(String pluginName, GroovyPluginScriptEngine scriptEngine, File srcFile)
      throws InvalidPluginException {
    super(pluginName, getPluginVersion(srcFile), load(scriptEngine, srcFile), ApiType.PLUGIN);
  }

  private static String getPluginVersion(File srcFile) {
    String srcFileName = srcFile.getName();
    int dashPos = srcFileName.lastIndexOf('-');
    int dotPos = srcFileName.lastIndexOf('.');
    return dashPos > 0 ? srcFileName.substring(dashPos + 1, dotPos) : "0";
  }

  @Override
  public Optional<PluginEntry> getEntry(String resourcePath) {
    return Optional.absent();
  }

  @Override
  public InputStream getInputStream(PluginEntry entry)
      throws IOException {
    throw new FileNotFoundException();
  }

  @Override
  public Enumeration<PluginEntry> entries() {
    return Collections.emptyEnumeration();
  }

  public static Set<Class<?>> load(GroovyPluginScriptEngine scriptEngine, File srcFile) throws InvalidPluginException {
    try {
      return scanGroovyScriptBindings(scriptEngine.loadScriptByName(srcFile
          .getName()));
    } catch (ResourceException | ScriptException e) {
      throw new InvalidPluginException(
          "Cannot compile and execute Groovy script " + srcFile, e);
    }
  }

  private static Set<Class<?>> scanGroovyScriptBindings(Class<?> scriptClass)
      throws InvalidPluginException {
    Set<Class<?>> classes = Sets.newHashSet();

    try {
      Method mainMethod = scriptClass.getMethod("main", String[].class);
      int modifiers = mainMethod.getModifiers();
      if (mainMethod != null && Modifier.isPublic(modifiers)
          && Modifier.isStatic(modifiers)) {
        classes.addAll(getMainBindings(scriptClass));
      }
    } catch (NoSuchMethodException e) {
      classes.add(scriptClass);

    } catch (SecurityException e) {
      throw new InvalidPluginException("Cannot access Groovy script class "
          + scriptClass.getName(), e);
    }
    return classes;
  }

  private static Set<Class<?>> getMainBindings(Class<?> scriptClass)
      throws InvalidPluginException {
    Set<Class<?>> classes = Sets.newHashSet();
    Binding binding = new Binding();
    Script script = InvokerHelper.createScript(scriptClass, binding);
    script.run();

    for (Object variable : binding.getVariables().keySet()) {
      Object value = binding.getVariable(variable.toString());
      if (value == null) {
        continue;
      }

      if (ArrayList.class.isAssignableFrom(value.getClass())) {
        classes.addAll(scanArrayOfObjectOrClass(value));
      } else {
        classes.add(scanObjectOrClass(value));
      }
    }

    return classes;
  }

  private static Set<Class<?>> scanArrayOfObjectOrClass(Object value)
      throws InvalidPluginException {
    Set<Class<?>> classes = Sets.newHashSet();
    ArrayList<?> list = (ArrayList<?>) value;
    for (Object element : list) {
      if (element == null) {
        continue;
      }
      classes.add(scanObjectOrClass(element));
    }
    return classes;
  }

  private static Class<?> scanObjectOrClass(Object element)
      throws InvalidPluginException {
    if (Class.class.isAssignableFrom(element.getClass())) {
      return (Class<?>) element;
    } else {
      return element.getClass();
    }
  }
}
