/*
 * 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.idea.blaze.base;

import com.intellij.mock.MockProject;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.extensions.DefaultPluginDescriptor;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.extensions.PluginDescriptor;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.extensions.impl.ExtensionPointImpl;
import com.intellij.openapi.extensions.impl.ExtensionsAreaImpl;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.SystemInfo;
import org.jetbrains.annotations.NotNull;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.picocontainer.MutablePicoContainer;

/**
 * Test base class.
 *
 * <p>
 *
 * <p>Provides a mock application and a mock project.
 */
public class BlazeTestCase {
  /** Test rule that ensures tests do not run on Windows (see http://b.android.com/222904) */
  public static class IgnoreOnWindowsRule implements TestRule {
    @NotNull
    @Override
    public Statement apply(Statement base, Description description) {
      if (SystemInfo.isWindows) {
        return new Statement() {
          @Override
          public void evaluate() throws Throwable {
            System.out.println(
                "Test \""
                    + description.getDisplayName()
                    + "\" does not run on Windows (see http://b.android.com/222904)");
          }
        };
      }
      return base;
    }
  }

  @Rule public IgnoreOnWindowsRule rule = new IgnoreOnWindowsRule();

  protected Project project;
  private ExtensionsAreaImpl extensionsArea;
  private Disposable testDisposable;

  private static class RootDisposable implements Disposable {
    @Override
    public void dispose() {}
  }

  /** A wrapper around the pico container used by IntelliJ's DI system */
  public static class Container {
    private final MutablePicoContainer container;

    Container(@NotNull MutablePicoContainer container) {
      this.container = container;
    }

    public <T> Container register(Class<T> klass, T instance) {
      this.container.registerComponentInstance(klass.getName(), instance);
      return this;
    }
  }

  @Before
  public final void setup() {
    testDisposable = new RootDisposable();
    TestUtils.createMockApplication(testDisposable);
    MutablePicoContainer applicationContainer =
        (MutablePicoContainer) ApplicationManager.getApplication().getPicoContainer();
    MockProject mockProject = TestUtils.mockProject(applicationContainer, testDisposable);

    Extensions.cleanRootArea(testDisposable);
    extensionsArea = (ExtensionsAreaImpl) Extensions.getRootArea();

    this.project = mockProject;

    initTest(new Container(applicationContainer), new Container(mockProject.getPicoContainer()));
  }

  @After
  public final void tearDown() {
    Disposer.dispose(testDisposable);
  }

  public final Project getProject() {
    return project;
  }

  protected void initTest(
      @NotNull Container applicationServices, @NotNull Container projectServices) {}

  protected <T> ExtensionPointImpl<T> registerExtensionPoint(
      @NotNull ExtensionPointName<T> name, @NotNull Class<T> type) {
    PluginDescriptor pluginDescriptor =
        new DefaultPluginDescriptor(PluginId.getId(type.getName()), type.getClassLoader());
    extensionsArea.registerExtensionPoint(name.getName(), type.getName(), pluginDescriptor);
    return extensionsArea.getExtensionPoint(name.getName());
  }
}
