/*
 * 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.sync;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.idea.blaze.base.async.AsyncUtil;
import com.google.idea.blaze.base.async.FutureUtil;
import com.google.idea.blaze.base.async.executor.BlazeExecutor;
import com.google.idea.blaze.base.experiments.ExperimentScope;
import com.google.idea.blaze.base.filecache.FileCaches;
import com.google.idea.blaze.base.ideinfo.RuleKey;
import com.google.idea.blaze.base.ideinfo.RuleMap;
import com.google.idea.blaze.base.metrics.Action;
import com.google.idea.blaze.base.model.BlazeProjectData;
import com.google.idea.blaze.base.model.SyncState;
import com.google.idea.blaze.base.model.primitives.TargetExpression;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.prefetch.PrefetchService;
import com.google.idea.blaze.base.projectview.ProjectViewManager;
import com.google.idea.blaze.base.projectview.ProjectViewSet;
import com.google.idea.blaze.base.projectview.ProjectViewVerifier;
import com.google.idea.blaze.base.projectview.section.sections.TargetSection;
import com.google.idea.blaze.base.rulemaps.ReverseDependencyMap;
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.scope.Scope;
import com.google.idea.blaze.base.scope.output.IssueOutput;
import com.google.idea.blaze.base.scope.output.PrintOutput;
import com.google.idea.blaze.base.scope.output.StatusOutput;
import com.google.idea.blaze.base.scope.scopes.BlazeConsoleScope;
import com.google.idea.blaze.base.scope.scopes.IdeaLogScope;
import com.google.idea.blaze.base.scope.scopes.IssuesScope;
import com.google.idea.blaze.base.scope.scopes.LoggedTimingScope;
import com.google.idea.blaze.base.scope.scopes.NotificationScope;
import com.google.idea.blaze.base.scope.scopes.PerformanceWarningScope;
import com.google.idea.blaze.base.scope.scopes.ProgressIndicatorScope;
import com.google.idea.blaze.base.scope.scopes.TimingScope;
import com.google.idea.blaze.base.settings.Blaze;
import com.google.idea.blaze.base.settings.BlazeImportSettings;
import com.google.idea.blaze.base.settings.BlazeUserSettings;
import com.google.idea.blaze.base.sync.BlazeSyncParams.SyncMode;
import com.google.idea.blaze.base.sync.BlazeSyncPlugin.ModuleEditor;
import com.google.idea.blaze.base.sync.SyncListener.SyncResult;
import com.google.idea.blaze.base.sync.aspects.BlazeIdeInterface;
import com.google.idea.blaze.base.sync.aspects.BlazeIdeInterface.BuildResult;
import com.google.idea.blaze.base.sync.data.BlazeDataStorage;
import com.google.idea.blaze.base.sync.data.BlazeProjectDataManagerImpl;
import com.google.idea.blaze.base.sync.projectstructure.ContentEntryEditor;
import com.google.idea.blaze.base.sync.projectstructure.ModuleEditorImpl;
import com.google.idea.blaze.base.sync.projectstructure.ModuleEditorProvider;
import com.google.idea.blaze.base.sync.projectview.LanguageSupport;
import com.google.idea.blaze.base.sync.projectview.WorkspaceLanguageSettings;
import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoderImpl;
import com.google.idea.blaze.base.sync.workspace.BlazeRoots;
import com.google.idea.blaze.base.sync.workspace.WorkingSet;
import com.google.idea.blaze.base.sync.workspace.WorkspacePathResolver;
import com.google.idea.blaze.base.sync.workspace.WorkspacePathResolverImpl;
import com.google.idea.blaze.base.util.SaveUtil;
import com.google.idea.blaze.base.vcs.BlazeVcsHandler;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Progressive;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.StandardFileSystems;
import com.intellij.openapi.vfs.VirtualFileManager;
import java.io.File;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Nullable;

/** Syncs the project with blaze. */
final class BlazeSyncTask implements Progressive {

  private static final Logger LOG = Logger.getInstance(BlazeSyncTask.class);

  private final Project project;
  private final BlazeImportSettings importSettings;
  private final WorkspaceRoot workspaceRoot;
  private final BlazeSyncParams syncParams;
  private final boolean showPerformanceWarnings;
  private long syncStartTime;

  BlazeSyncTask(
      Project project, BlazeImportSettings importSettings, final BlazeSyncParams syncParams) {
    this.project = project;
    this.importSettings = importSettings;
    this.workspaceRoot = WorkspaceRoot.fromImportSettings(importSettings);
    this.syncParams = syncParams;
    this.showPerformanceWarnings = BlazeUserSettings.getInstance().getShowPerformanceWarnings();
  }

  @Override
  public void run(final ProgressIndicator indicator) {
    Scope.root(
        (BlazeContext context) -> {
          context.push(new ExperimentScope());
          if (showPerformanceWarnings) {
            context.push(new PerformanceWarningScope());
          }
          context
              .push(new ProgressIndicatorScope(indicator))
              .push(new TimingScope("Sync"))
              .push(new LoggedTimingScope(project, Action.SYNC_TOTAL_TIME));

          if (!syncParams.backgroundSync) {
            context
                .push(new BlazeConsoleScope.Builder(project, indicator).build())
                .push(new IssuesScope(project))
                .push(new IdeaLogScope())
                .push(
                    new NotificationScope(
                        project, "Sync", "Sync project", "Sync successful", "Sync failed"));
          }

          context.output(new StatusOutput("Syncing project..."));
          syncProject(context);
        });
  }

  /** Returns true if sync successfully completed */
  @VisibleForTesting
  boolean syncProject(BlazeContext context) {
    SyncResult syncResult = SyncResult.FAILURE;
    try {
      SaveUtil.saveAllFiles();
      onSyncStart(project, context);
      syncResult = doSyncProject(context);
    } catch (AssertionError | Exception e) {
      LOG.error(e);
      IssueOutput.error("Internal error: " + e.getMessage()).submit(context);
    } finally {
      afterSync(project, context, syncResult);
    }
    return syncResult == SyncResult.SUCCESS || syncResult == SyncResult.PARTIAL_SUCCESS;
  }

  /** @return true if sync successfully completed */
  private SyncResult doSyncProject(final BlazeContext context) {
    this.syncStartTime = System.currentTimeMillis();

    if (importSettings.getProjectViewFile() == null) {
      IssueOutput.error(
              "This project looks like it's been opened from an old version of ASwB. "
                  + "That is unfortunately not supported. Please reimport your project.")
          .submit(context);
      return SyncResult.FAILURE;
    }

    @Nullable BlazeProjectData oldBlazeProjectData = null;
    if (syncParams.syncMode != SyncMode.FULL) {
      oldBlazeProjectData =
          BlazeProjectDataManagerImpl.getImpl(project).loadProjectRoot(context, importSettings);
    }

    BlazeVcsHandler vcsHandler = null;
    for (BlazeVcsHandler candidate : BlazeVcsHandler.EP_NAME.getExtensions()) {
      if (candidate.handlesProject(Blaze.getBuildSystem(project), workspaceRoot)) {
        vcsHandler = candidate;
        break;
      }
    }
    if (vcsHandler == null) {
      IssueOutput.error("Could not find a VCS handler").submit(context);
      return SyncResult.FAILURE;
    }

    ListeningExecutorService executor = BlazeExecutor.getInstance().getExecutor();
    ListenableFuture<BlazeRoots> blazeRootsFuture =
        BlazeRoots.compute(project, workspaceRoot, context);
    ListenableFuture<WorkingSet> workingSetFuture =
        vcsHandler.getWorkingSet(project, context, workspaceRoot, executor);

    BlazeRoots blazeRoots =
        FutureUtil.waitForFuture(context, blazeRootsFuture)
            .timed(Blaze.buildSystemName(project) + "Roots")
            .withProgressMessage(
                String.format("Running %s info...", Blaze.buildSystemName(project)))
            .onError(String.format("Could not get %s roots", Blaze.buildSystemName(project)))
            .run()
            .result();
    if (blazeRoots == null) {
      return SyncResult.FAILURE;
    }

    WorkspacePathResolverAndProjectView workspacePathResolverAndProjectView =
        computeWorkspacePathResolverAndProjectView(context, blazeRoots, vcsHandler, executor);
    if (workspacePathResolverAndProjectView == null) {
      return SyncResult.FAILURE;
    }
    WorkspacePathResolver workspacePathResolver =
        workspacePathResolverAndProjectView.workspacePathResolver;
    ArtifactLocationDecoder artifactLocationDecoder =
        new ArtifactLocationDecoderImpl(blazeRoots, workspacePathResolver);
    ProjectViewSet projectViewSet = workspacePathResolverAndProjectView.projectViewSet;

    WorkspaceLanguageSettings workspaceLanguageSettings =
        LanguageSupport.createWorkspaceLanguageSettings(context, projectViewSet);
    if (workspaceLanguageSettings == null) {
      return SyncResult.FAILURE;
    }

    if (!ProjectViewVerifier.verifyProjectView(
        context, workspaceRoot, projectViewSet, workspaceLanguageSettings)) {
      return SyncResult.FAILURE;
    }

    final BlazeProjectData newBlazeProjectData;

    WorkingSet workingSet =
        FutureUtil.waitForFuture(context, workingSetFuture)
            .timed("WorkingSet")
            .withProgressMessage("Computing VCS working set...")
            .onError("Could not compute working set")
            .run()
            .result();
    if (context.isCancelled()) {
      return SyncResult.CANCELLED;
    }
    if (context.hasErrors()) {
      return SyncResult.FAILURE;
    }

    if (workingSet != null) {
      printWorkingSet(context, workingSet);
    }

    BuildResult ideInfoResult = BuildResult.SUCCESS;
    BuildResult ideResolveResult = BuildResult.SUCCESS;
    if (syncParams.syncMode != SyncMode.RESTORE_EPHEMERAL_STATE || oldBlazeProjectData == null) {
      SyncState.Builder syncStateBuilder = new SyncState.Builder();
      SyncState previousSyncState =
          oldBlazeProjectData != null ? oldBlazeProjectData.syncState : null;

      boolean syncPluginRequiresBuild = false;
      for (BlazeSyncPlugin syncPlugin : BlazeSyncPlugin.EP_NAME.getExtensions()) {
        syncPluginRequiresBuild |= syncPlugin.requiresResolveIdeArtifacts();
      }

      List<TargetExpression> targets = Lists.newArrayList();
      if (syncParams.addProjectViewTargets || oldBlazeProjectData == null) {
        targets.addAll(projectViewSet.listItems(TargetSection.KEY));
      }
      if (syncParams.addWorkingSet && workingSet != null) {
        targets.addAll(getWorkingSetTargets(workingSet));
      }
      targets.addAll(syncParams.targetExpressions);

      boolean mergeWithOldState = !syncParams.addProjectViewTargets;
      BlazeIdeInterface.IdeResult ideQueryResult =
          getIdeQueryResult(
              project,
              context,
              projectViewSet,
              targets,
              workspaceLanguageSettings,
              artifactLocationDecoder,
              syncStateBuilder,
              previousSyncState,
              mergeWithOldState);
      if (context.isCancelled()) {
        return SyncResult.CANCELLED;
      }
      if (ideQueryResult.ruleMap == null || ideQueryResult.buildResult == BuildResult.FATAL_ERROR) {
        context.setHasError();
        return SyncResult.FAILURE;
      }

      RuleMap ruleMap = ideQueryResult.ruleMap;
      ideInfoResult = ideQueryResult.buildResult;

      ListenableFuture<ImmutableMultimap<RuleKey, RuleKey>> reverseDependenciesFuture =
          BlazeExecutor.getInstance().submit(() -> ReverseDependencyMap.createRdepsMap(ruleMap));

      boolean doResolve = syncPluginRequiresBuild || oldBlazeProjectData == null;
      if (doResolve) {
        ideResolveResult =
            resolveIdeArtifacts(project, context, workspaceRoot, projectViewSet, targets);
        if (ideResolveResult == BuildResult.FATAL_ERROR) {
          context.setHasError();
          return SyncResult.FAILURE;
        }
      }
      if (context.isCancelled()) {
        return SyncResult.CANCELLED;
      }

      Scope.push(
          context,
          (childContext) -> {
            childContext.push(new TimingScope("UpdateSyncState"));
            for (BlazeSyncPlugin syncPlugin : BlazeSyncPlugin.EP_NAME.getExtensions()) {
              syncPlugin.updateSyncState(
                  project,
                  childContext,
                  workspaceRoot,
                  projectViewSet,
                  workspaceLanguageSettings,
                  blazeRoots,
                  workingSet,
                  workspacePathResolver,
                  artifactLocationDecoder,
                  ruleMap,
                  syncStateBuilder,
                  previousSyncState);
            }
          });

      ImmutableMultimap<RuleKey, RuleKey> reverseDependencies =
          FutureUtil.waitForFuture(context, reverseDependenciesFuture)
              .timed("ReverseDependencies")
              .onError("Failed to compute reverse dependency map")
              .run()
              .result();
      if (reverseDependencies == null) {
        return SyncResult.FAILURE;
      }

      newBlazeProjectData =
          new BlazeProjectData(
              syncStartTime,
              ruleMap,
              blazeRoots,
              workingSet,
              workspacePathResolver,
              artifactLocationDecoder,
              workspaceLanguageSettings,
              syncStateBuilder.build(),
              reverseDependencies,
              vcsHandler.getVcsName());
    } else {
      // Restore project based on old blaze project data
      newBlazeProjectData = oldBlazeProjectData;
    }

    FileCaches.onSync(project, context, projectViewSet, newBlazeProjectData, syncParams.syncMode);
    ListenableFuture<?> prefetch =
        PrefetchService.getInstance().prefetchProjectFiles(project, newBlazeProjectData);
    FutureUtil.waitForFuture(context, prefetch)
        .withProgressMessage("Prefetching files...")
        .timed("PrefetchFiles")
        .onError("Prefetch failed")
        .run();

    boolean success =
        updateProject(project, context, projectViewSet, oldBlazeProjectData, newBlazeProjectData);
    if (!success) {
      return SyncResult.FAILURE;
    }

    SyncResult syncResult = SyncResult.SUCCESS;

    if (ideInfoResult == BuildResult.BUILD_ERROR || ideResolveResult == BuildResult.BUILD_ERROR) {
      final String errorType =
          ideInfoResult == BuildResult.BUILD_ERROR ? "BUILD file errors" : "compilation errors";

      String message =
          String.format(
              "Sync was successful, but there were %s. "
                  + "The project may not be fully updated or resolve until fixed. "
                  + "If the errors are from your working set, please uncheck "
                  + "'Blaze > Expand Sync to Working Set' and try again.",
              errorType);
      context.output(PrintOutput.error(message));
      IssueOutput.warn(message).submit(context);
      syncResult = SyncResult.PARTIAL_SUCCESS;
    }

    onSyncComplete(project, context, projectViewSet, newBlazeProjectData, syncResult);
    return syncResult;
  }

  static class WorkspacePathResolverAndProjectView {
    final WorkspacePathResolver workspacePathResolver;
    final ProjectViewSet projectViewSet;

    public WorkspacePathResolverAndProjectView(
        WorkspacePathResolver workspacePathResolver, ProjectViewSet projectViewSet) {
      this.workspacePathResolver = workspacePathResolver;
      this.projectViewSet = projectViewSet;
    }
  }

  private WorkspacePathResolverAndProjectView computeWorkspacePathResolverAndProjectView(
      BlazeContext context,
      BlazeRoots blazeRoots,
      BlazeVcsHandler vcsHandler,
      ListeningExecutorService executor) {
    context.output(new StatusOutput("Updating VCS..."));

    for (int i = 0; i < 3; ++i) {
      WorkspacePathResolver vcsWorkspacePathResolver = null;
      BlazeVcsHandler.BlazeVcsSyncHandler vcsSyncHandler =
          vcsHandler.createSyncHandler(project, workspaceRoot);
      if (vcsSyncHandler != null) {
        boolean ok =
            Scope.push(
                context,
                (childContext) -> {
                  childContext.push(new TimingScope("UpdateVcs"));
                  return vcsSyncHandler.update(context, blazeRoots, executor);
                });
        if (!ok) {
          return null;
        }
        vcsWorkspacePathResolver = vcsSyncHandler.getWorkspacePathResolver();
      }

      WorkspacePathResolver workspacePathResolver =
          vcsWorkspacePathResolver != null
              ? vcsWorkspacePathResolver
              : new WorkspacePathResolverImpl(workspaceRoot, blazeRoots);

      ProjectViewSet projectViewSet =
          ProjectViewManager.getInstance(project).reloadProjectView(context, workspacePathResolver);
      if (projectViewSet == null) {
        return null;
      }

      if (vcsSyncHandler != null) {
        BlazeVcsHandler.BlazeVcsSyncHandler.ValidationResult validationResult =
            vcsSyncHandler.validateProjectView(context, projectViewSet);
        switch (validationResult) {
          case OK:
            // Fall-through and return
            break;
          case Error:
            return null;
          case RestartSync:
            continue;
          default:
            // Cannot happen
            return null;
        }
      }

      return new WorkspacePathResolverAndProjectView(workspacePathResolver, projectViewSet);
    }
    return null;
  }

  private void printWorkingSet(BlazeContext context, WorkingSet workingSet) {
    List<String> messages = Lists.newArrayList();
    messages.addAll(
        workingSet
            .addedFiles
            .stream()
            .map(file -> file.relativePath() + " (added)")
            .collect(Collectors.toList()));
    messages.addAll(
        workingSet
            .modifiedFiles
            .stream()
            .map(file -> file.relativePath() + " (modified)")
            .collect(Collectors.toList()));
    Collections.sort(messages);

    if (messages.isEmpty()) {
      context.output(PrintOutput.log("Your working set is empty"));
      return;
    }
    int maxFiles = 20;
    for (String message : Iterables.limit(messages, maxFiles)) {
      context.output(PrintOutput.log("  " + message));
    }
    if (messages.size() > maxFiles) {
      context.output(PrintOutput.log(String.format("  (and %d more)", messages.size() - maxFiles)));
    }
  }

  private Collection<? extends TargetExpression> getWorkingSetTargets(WorkingSet workingSet) {
    List<TargetExpression> result = Lists.newArrayList();
    for (WorkspacePath workspacePath :
        Iterables.concat(workingSet.addedFiles, workingSet.modifiedFiles)) {
      File buildFile = workspaceRoot.fileForPath(workspacePath);
      if (buildFile.getName().equals("BUILD")) {
        result.add(
            TargetExpression.allFromPackageNonRecursive(
                workspaceRoot.workspacePathFor(buildFile.getParentFile())));
      }
    }
    return result;
  }

  private BlazeIdeInterface.IdeResult getIdeQueryResult(
      Project project,
      BlazeContext parentContext,
      ProjectViewSet projectViewSet,
      List<TargetExpression> targets,
      WorkspaceLanguageSettings workspaceLanguageSettings,
      ArtifactLocationDecoder artifactLocationDecoder,
      SyncState.Builder syncStateBuilder,
      @Nullable SyncState previousSyncState,
      boolean mergeWithOldState) {

    return Scope.push(
        parentContext,
        context -> {
          context.push(new TimingScope("IdeQuery"));
          context.output(new StatusOutput("Building IDE info files..."));
          context.setPropagatesErrors(false);

          BlazeIdeInterface blazeIdeInterface = BlazeIdeInterface.getInstance();
          return blazeIdeInterface.updateRuleMap(
              project,
              context,
              workspaceRoot,
              projectViewSet,
              targets,
              workspaceLanguageSettings,
              artifactLocationDecoder,
              syncStateBuilder,
              previousSyncState,
              mergeWithOldState);
        });
  }

  private static BuildResult resolveIdeArtifacts(
      Project project,
      BlazeContext parentContext,
      WorkspaceRoot workspaceRoot,
      ProjectViewSet projectViewSet,
      List<TargetExpression> targetExpressions) {
    return Scope.push(
        parentContext,
        context -> {
          context
              .push(new LoggedTimingScope(project, Action.BLAZE_BUILD_DURING_SYNC))
              .push(new TimingScope(Blaze.buildSystemName(project) + "Build"));
          context.output(new StatusOutput("Building IDE resolve files..."));

          // We don't want IDE resolve errors to fail the whole sync
          context.setPropagatesErrors(false);

          if (targetExpressions.isEmpty()) {
            return BuildResult.SUCCESS;
          }
          BlazeIdeInterface blazeIdeInterface = BlazeIdeInterface.getInstance();
          return blazeIdeInterface.resolveIdeArtifacts(
              project, context, workspaceRoot, projectViewSet, targetExpressions);
        });
  }

  private boolean updateProject(
      Project project,
      BlazeContext parentContext,
      ProjectViewSet projectViewSet,
      @Nullable BlazeProjectData oldBlazeProjectData,
      BlazeProjectData newBlazeProjectData) {
    return Scope.push(
        parentContext,
        context -> {
          context
              .push(new LoggedTimingScope(project, Action.SYNC_IMPORT_DATA_TIME))
              .push(new TimingScope("UpdateProjectStructure"));
          context.output(new StatusOutput("Committing project structure..."));

          try {
            AsyncUtil.executeProjectChangeAction(
                () ->
                    ProjectRootManagerEx.getInstanceEx(this.project)
                        .mergeRootsChangesDuring(
                            () -> {
                              updateSdk(context, projectViewSet, newBlazeProjectData);
                              updateProjectStructure(
                                  context,
                                  importSettings,
                                  projectViewSet,
                                  newBlazeProjectData,
                                  oldBlazeProjectData);
                            }));
          } catch (Throwable t) {
            IssueOutput.error("Internal error. Error: " + t).submit(context);
            LOG.error(t);
            return false;
          }

          BlazeProjectDataManagerImpl.getImpl(this.project)
              .saveProject(importSettings, newBlazeProjectData);
          return true;
        });
  }

  private void updateSdk(
      BlazeContext context, ProjectViewSet projectViewSet, BlazeProjectData newBlazeProjectData) {
    for (BlazeSyncPlugin syncPlugin : BlazeSyncPlugin.EP_NAME.getExtensions()) {
      syncPlugin.updateSdk(project, context, projectViewSet, newBlazeProjectData);
    }
  }

  private void updateProjectStructure(
      BlazeContext context,
      BlazeImportSettings importSettings,
      ProjectViewSet projectViewSet,
      BlazeProjectData newBlazeProjectData,
      @Nullable BlazeProjectData oldBlazeProjectData) {

    ModuleEditorImpl moduleEditor =
        ModuleEditorProvider.getInstance().getModuleEditor(project, importSettings);

    ModuleType workspaceModuleType = null;
    for (BlazeSyncPlugin syncPlugin : BlazeSyncPlugin.EP_NAME.getExtensions()) {
      workspaceModuleType =
          syncPlugin.getWorkspaceModuleType(
              newBlazeProjectData.workspaceLanguageSettings.getWorkspaceType());
      if (workspaceModuleType != null) {
        break;
      }
    }
    if (workspaceModuleType == null) {
      workspaceModuleType = ModuleType.EMPTY;
      IssueOutput.warn("Could not set module type for workspace module.").submit(context);
    }

    Module workspaceModule = moduleEditor.createModule(".workspace", workspaceModuleType);
    ModifiableRootModel workspaceModifiableModel = moduleEditor.editModule(workspaceModule);

    ContentEntryEditor.createContentEntries(
        project,
        context,
        workspaceRoot,
        projectViewSet,
        newBlazeProjectData,
        workspaceModifiableModel);

    for (BlazeSyncPlugin blazeSyncPlugin : BlazeSyncPlugin.EP_NAME.getExtensions()) {
      blazeSyncPlugin.updateProjectStructure(
          project,
          context,
          workspaceRoot,
          projectViewSet,
          newBlazeProjectData,
          oldBlazeProjectData,
          moduleEditor,
          workspaceModule,
          workspaceModifiableModel);
    }

    createProjectDataDirectoryModule(
        moduleEditor, new File(importSettings.getProjectDataDirectory()), workspaceModuleType);

    moduleEditor.commitWithGc(context);
  }

  /**
   * Creates a module that includes the user's data directory.
   *
   * <p>This is useful to be able to edit the project view without IntelliJ complaining it's outside
   * the project.
   */
  private void createProjectDataDirectoryModule(
      ModuleEditor moduleEditor, File projectDataDirectory, ModuleType moduleType) {
    Module module = moduleEditor.createModule(".project-data-dir", moduleType);
    ModifiableRootModel modifiableModel = moduleEditor.editModule(module);
    ContentEntry rootContentEntry =
        modifiableModel.addContentEntry(pathToUrl(projectDataDirectory));
    rootContentEntry.addExcludeFolder(pathToUrl(new File(projectDataDirectory, ".idea")));
    rootContentEntry.addExcludeFolder(
        pathToUrl(BlazeDataStorage.getProjectDataDir(importSettings)));
  }

  private static String pathToUrl(File path) {
    String filePath = FileUtil.toSystemIndependentName(path.getPath());
    return VirtualFileManager.constructUrl(StandardFileSystems.FILE_PROTOCOL, filePath);
  }

  private static void onSyncStart(Project project, BlazeContext context) {
    final SyncListener[] syncListeners = SyncListener.EP_NAME.getExtensions();
    for (SyncListener syncListener : syncListeners) {
      syncListener.onSyncStart(project, context);
    }
  }

  private static void afterSync(Project project, BlazeContext context, SyncResult syncResult) {
    final SyncListener[] syncListeners = SyncListener.EP_NAME.getExtensions();
    for (SyncListener syncListener : syncListeners) {
      syncListener.afterSync(project, context, syncResult);
    }
  }

  private void onSyncComplete(
      Project project,
      BlazeContext context,
      ProjectViewSet projectViewSet,
      BlazeProjectData blazeProjectData,
      SyncResult syncResult) {
    validate(project, context, blazeProjectData);

    final SyncListener[] syncListeners = SyncListener.EP_NAME.getExtensions();
    for (SyncListener syncListener : syncListeners) {
      syncListener.onSyncComplete(
          project, context, importSettings, projectViewSet, blazeProjectData, syncResult);
    }
  }

  private static void validate(
      Project project, BlazeContext context, BlazeProjectData blazeProjectData) {
    for (BlazeSyncPlugin syncPlugin : BlazeSyncPlugin.EP_NAME.getExtensions()) {
      syncPlugin.validate(project, context, blazeProjectData);
    }
  }
}
