package jetbrains.mps.tool.environment;

/*Generated by MPS */

import jetbrains.mps.annotations.GeneratedClass;
import org.jetbrains.annotations.NotNull;
import jetbrains.mps.project.Project;
import java.io.File;
import jetbrains.mps.core.platform.Platform;

/**
 * Intended to be used in headless runs, represents working MPS environment.
 * Currently it is cached for all tests in the case of group test runs (suites).
 * To initialize environment in a lazy way (trying to get cached environment if available)
 * use MPSEnvironment or IdeaEnvironment #getOrCreate methods.
 * Use MPSEnvironment if you do not need the idea platform, IdeaEnvironment otherwise.
 * These methods use ref counting to dispose the environment in the right time (at the end of suite or at the end of the test);
 * they call the method #retain to increase the reference counter.
 * 
 * The common pattern in tests is to call #getOrCreate method in the @BeforeClass section,
 * and call #release method in the @AfterClass section.
 * There are helping base classes: PlatformMpsTest and CoreMpsTest for the IdeaEnvironment and MpsEnvironment correspondingly.
 * 
 * AP: TODO consider merging all the project creation methods
 * 
 * There are two base implementations, {@link jetbrains.mps.tool.environment.EnvironmentBase } which is deemed for full-fledged runtime instances, and
 *  {@link jetbrains.mps.tool.environment.AbstractEnvironment } generally intended for lightweight, API-like access to existing runtime instance.
 */
@GeneratedClass(node = "r:2876f1ee-0b45-4db5-8c09-0682cdee5c67(jetbrains.mps.tool.environment)/824372260173098491", model = "r:2876f1ee-0b45-4db5-8c09-0682cdee5c67(jetbrains.mps.tool.environment)")
public interface Environment {
  /**
   * Creates and opens an empty project
   * 
   * @return newly created Project.
   */
  @NotNull
  Project createEmptyProject();

  /**
   * Creates a project and opens it according to the given strategy
   * 
   * @return newly created Project constructed as the strategy suggests. It is already opened.
   */
  @NotNull
  Project createProject(@NotNull ProjectStrategy strategy);

  @NotNull
  Project openProject(@NotNull File projectFile);

  /**
   * Discards previously opened project. 
   * Environment does its best to close the project but may choose to ignore request in certain scenarions (like in-process test execution, when closing an active project may affect user experience)
   * 
   * @param project an instance obtained from {@link #openProject(java.io.File)}
   */
  void closeProject(@NotNull Project project);

  /**
   * disposes the environment for real, does not consider ref counts
   */
  void dispose();

  /**
   * flushes all #invokeAndLater calls and all ModelAccess event queue if needed
   */
  void flushAllEvents();

  /**
   * 
   * @return MPS (its platform aspect) of this tooling environment, not null when initialized.
   */
  Platform getPlatform();
}
