/*
 * 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.*;
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 org.jetbrains.annotations.NotNull;
import org.junit.After;
import org.junit.Before;
import org.picocontainer.MutablePicoContainer;

/**
 * Test base class.
 * <p/>
 * <p>Provides a mock application and a mock project.
 */
public class BlazeTestCase {

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

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

  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) {
    ExtensionPointImpl<T> extensionPoint = new ExtensionPointImpl<T>(
      name.getName(),
      type.getName(),
      ExtensionPoint.Kind.INTERFACE,
      extensionsArea,
      null,
      new Extensions.SimpleLogProvider(),
      new DefaultPluginDescriptor(PluginId.getId(type.getName()), type.getClassLoader())
    );
    extensionsArea.registerExtensionPoint(extensionPoint);
    return extensionPoint;
  }
}
