// Copyright 2016 The Bazel Authors. All rights reserved.
//
// 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.devtools.bazel.e4b;

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;

import com.google.common.collect.ImmutableList;
import com.google.devtools.bazel.e4b.command.BazelCommand;
import com.google.devtools.bazel.e4b.command.BazelCommand.BazelInstance;
import com.google.devtools.bazel.e4b.command.BazelNotFoundException;

/**
 * The activator class controls the plug-in life cycle
 */
public class Activator extends AbstractUIPlugin {

  // The plug-in ID
  public static final String PLUGIN_ID = "com.google.devtools.bazel.e4b"; //$NON-NLS-1$

  // The shared instance
  private static Activator plugin;

  private BazelCommand command;

  public static final String DEFAULT_BAZEL_PATH = "/usr/local/bin/bazel";

  /**
   * The constructor
   */
  public Activator() {}

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
   */
  public void start(BundleContext context) throws Exception {
    plugin = this;
    super.start(context);
    this.command = new BazelCommand(new BazelAspectLocationImpl(), new CommandConsoleFactoryImpl());
    // Get the bazel path from the settings
    this.command.setBazelPath(getPreferenceStore().getString("BAZEL_PATH"));
    getPreferenceStore().addPropertyChangeListener(new IPropertyChangeListener() {
      @Override
      public void propertyChange(PropertyChangeEvent event) {
        if (event.getProperty().equals("BAZEL_PATH")) {
          command.setBazelPath(event.getNewValue().toString());
        }
      }
    });
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
   */
  public void stop(BundleContext context) throws Exception {
    plugin = null;
    this.command = null;
    super.stop(context);
  }

  /**
   * Returns the shared instance
   *
   * @return the shared instance
   */
  public static Activator getDefault() {
    return plugin;
  }

  /**
   * Returns the unique instance of {@link BazelCommand}.
   */
  public BazelCommand getCommand() {
    return command;
  }


  /**
   * List targets configure for <code>project</code>. Each project configured for Bazel is
   * configured to track certain targets and this function fetch this list from the project
   * preferences.
   */
  public static List<String> getTargets(IProject project) throws BackingStoreException {
    // Get the list of targets from the preferences
    IScopeContext projectScope = new ProjectScope(project);
    Preferences projectNode = projectScope.getNode(PLUGIN_ID);
    ImmutableList.Builder<String> builder = ImmutableList.builder();
    for (String s : projectNode.keys()) {
      if (s.startsWith("target")) {
        builder.add(projectNode.get(s, ""));
      }
    }
    return builder.build();
  }

  /**
   * Return the {@link BazelInstance} corresponding to the given <code>project</code>. It looks for
   * the instance that runs for the workspace root configured for that project.
   * 
   * @throws BazelNotFoundException
   */
  public static BazelCommand.BazelInstance getBazelCommandInstance(IProject project)
      throws BackingStoreException, IOException, InterruptedException, BazelNotFoundException {
    IScopeContext projectScope = new ProjectScope(project.getProject());
    Preferences projectNode = projectScope.getNode(Activator.PLUGIN_ID);
    File workspaceRoot =
        new File(projectNode.get("workspaceRoot", project.getLocation().toFile().toString()));
    return getDefault().getCommand().getInstance(workspaceRoot);
  }

  /**
   * Log an error to eclipse.
   */
  public static void error(String message) {
    plugin.getLog().log(new Status(Status.ERROR, PLUGIN_ID, message));
  }

  /**
   * Log an error to eclipse, with an attached exception.
   */
  public static void error(String message, Throwable exception) {
    plugin.getLog().log(new Status(Status.ERROR, PLUGIN_ID, message, exception));
  }
}
