/*
 * 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;
  protected 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());
  }
}
