/*
 * Copyright 2000-2014 JetBrains s.r.o.
 *
 * 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.intellij.execution.runners;

import com.intellij.execution.*;
import com.intellij.execution.configurations.ConfigurationPerRunnerSettings;
import com.intellij.execution.configurations.RunProfile;
import com.intellij.execution.configurations.RunProfileState;
import com.intellij.execution.configurations.RunnerSettings;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.DataKey;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.UserDataHolderBase;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;

import static com.intellij.openapi.actionSystem.LangDataKeys.*;

public class ExecutionEnvironment extends UserDataHolderBase implements Disposable {
  private static final AtomicLong myIdHolder = new AtomicLong(1L);

  @NotNull private final Project myProject;

  @NotNull private RunProfile myRunProfile;
  @NotNull private final Executor myExecutor;
  @NotNull private ExecutionTarget myTarget;

  @Nullable private RunnerSettings myRunnerSettings;
  @Nullable private ConfigurationPerRunnerSettings myConfigurationSettings;
  @Nullable private final RunnerAndConfigurationSettings myRunnerAndConfigurationSettings;
  @Nullable private RunContentDescriptor myContentToReuse;
  private final ProgramRunner<?> myRunner;
  private long myExecutionId = 0;
  @Nullable private DataContext myDataContext;

  @TestOnly
  public ExecutionEnvironment() {
    myProject = null;
    myContentToReuse = null;
    myRunnerAndConfigurationSettings = null;
    myExecutor = null;
    myRunner = null;
  }

  public ExecutionEnvironment(@NotNull Executor executor,
                              @NotNull ProgramRunner runner,
                              @NotNull RunnerAndConfigurationSettings configuration,
                              @NotNull Project project) {
    this(configuration.getConfiguration(),
         executor,
         DefaultExecutionTarget.INSTANCE,
         project,
         configuration.getRunnerSettings(runner),
         configuration.getConfigurationSettings(runner),
         null,
         null,
         runner);
  }

  /**
   * @deprecated, use {@link com.intellij.execution.runners.ExecutionEnvironmentBuilder} instead
   * to remove in IDEA 14
   */
  @TestOnly
  public ExecutionEnvironment(@NotNull Executor executor,
                              @NotNull final ProgramRunner runner,
                              @NotNull final ExecutionTarget target,
                              @NotNull final RunnerAndConfigurationSettings configuration,
                              @NotNull Project project) {
    this(configuration.getConfiguration(),
         executor,
         target,
         project,
         configuration.getRunnerSettings(runner),
         configuration.getConfigurationSettings(runner),
         null,
         configuration,
         runner);
  }

  /**
   * @deprecated, use {@link com.intellij.execution.runners.ExecutionEnvironmentBuilder} instead
   * to remove in IDEA 15
   */
  public ExecutionEnvironment(@NotNull RunProfile runProfile,
                              @NotNull Executor executor,
                              @NotNull Project project,
                              @Nullable RunnerSettings runnerSettings) {
    //noinspection ConstantConditions
    this(runProfile, executor, DefaultExecutionTarget.INSTANCE, project, runnerSettings, null, null, null, RunnerRegistry.getInstance().getRunner(executor.getId(), runProfile));
  }

  ExecutionEnvironment(@NotNull RunProfile runProfile,
                       @NotNull Executor executor,
                       @NotNull ExecutionTarget target,
                       @NotNull Project project,
                       @Nullable RunnerSettings runnerSettings,
                       @Nullable ConfigurationPerRunnerSettings configurationSettings,
                       @Nullable RunContentDescriptor contentToReuse,
                       @Nullable RunnerAndConfigurationSettings settings,
                       @NotNull ProgramRunner<?> runner) {
    myExecutor = executor;
    myTarget = target;
    myRunProfile = runProfile;
    myRunnerSettings = runnerSettings;
    myConfigurationSettings = configurationSettings;
    myProject = project;
    setContentToReuse(contentToReuse);
    myRunnerAndConfigurationSettings = settings;

    myRunner = runner;
  }

  @Override
  public void dispose() {
    myContentToReuse = null;
  }

  @NotNull
  public Project getProject() {
    return myProject;
  }

  @NotNull
  public ExecutionTarget getExecutionTarget() {
    return myTarget;
  }

  @NotNull
  public RunProfile getRunProfile() {
    return myRunProfile;
  }

  @Nullable
  public RunnerAndConfigurationSettings getRunnerAndConfigurationSettings() {
    return myRunnerAndConfigurationSettings;
  }

  @Nullable
  public RunContentDescriptor getContentToReuse() {
    return myContentToReuse;
  }

  public void setContentToReuse(@Nullable RunContentDescriptor contentToReuse) {
    myContentToReuse = contentToReuse;

    if (contentToReuse != null) {
      Disposer.register(contentToReuse, this);
    }
  }

  @Nullable
  @Deprecated
  /**
   * Use {@link #getRunner()} instead
   * to remove in IDEA 15
   */
  public String getRunnerId() {
    return myRunner.getRunnerId();
  }

  @NotNull
  public ProgramRunner<?> getRunner() {
    return myRunner;
  }

  @Nullable
  public RunnerSettings getRunnerSettings() {
    return myRunnerSettings;
  }

  @Nullable
  public ConfigurationPerRunnerSettings getConfigurationSettings() {
    return myConfigurationSettings;
  }

  @Nullable
  public RunProfileState getState() throws ExecutionException {
    return myRunProfile.getState(myExecutor, this);
  }

  public long assignNewExecutionId() {
    myExecutionId = myIdHolder.incrementAndGet();
    return myExecutionId;
  }

  public void setExecutionId(long executionId) {
    myExecutionId = executionId;
  }

  public long getExecutionId() {
    return myExecutionId;
  }

  @NotNull
  public Executor getExecutor() {
    return myExecutor;
  }

  @Override
  public String toString() {
    if (myRunnerAndConfigurationSettings != null) {
      return myRunnerAndConfigurationSettings.getName();
    }
    else if (myRunProfile != null) {
      return myRunProfile.getName();
    }
    else if (myContentToReuse != null) {
      return myContentToReuse.getDisplayName();
    }
    return super.toString();
  }

  void setDataContext(@NotNull DataContext dataContext) {
    myDataContext = CachingDataContext.cacheIfNeed(dataContext);
  }

  @Nullable
  public DataContext getDataContext() {
    return myDataContext;
  }

  private static class CachingDataContext implements DataContext {
    private static final DataKey[] keys = {PROJECT, PROJECT_FILE_DIRECTORY, EDITOR, VIRTUAL_FILE, MODULE, PSI_FILE};
    private final Map<String, Object> values = new HashMap<String, Object>();

    @NotNull
    static CachingDataContext cacheIfNeed(@NotNull DataContext context) {
      if (context instanceof CachingDataContext)
        return (CachingDataContext)context;
      return new CachingDataContext(context);
    }

    private CachingDataContext(DataContext context) {
      for (DataKey key : keys) {
        values.put(key.getName(), key.getData(context));
      }
    }

    @Override
    public Object getData(@NonNls String dataId) {
        return values.get(dataId);
    }
  }
}
