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

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.idea.blaze.base.io.FileAttributeProvider;
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.scope.output.PrintOutput;
import com.google.idea.blaze.base.settings.BlazeImportSettings;
import com.google.idea.blaze.base.sync.BlazeSyncPlugin;
import com.google.idea.blaze.base.sync.data.BlazeDataStorage;
import com.intellij.ide.highlighter.ModuleFileType;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.ModifiableModuleModel;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.CompilerModuleExtension;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.impl.ModifiableModelCommitter;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;

/** Module editor implementation. */
public class ModuleEditorImpl implements BlazeSyncPlugin.ModuleEditor {
  private static final Logger logger = Logger.getInstance(ModuleEditorImpl.class.getName());
  private static final String EXTERNAL_SYSTEM_ID_KEY = "external.system.id";
  private static final String EXTERNAL_SYSTEM_ID_VALUE = "Blaze";

  private final Project project;
  private final ModifiableModuleModel moduleModel;
  private final File imlDirectory;
  @VisibleForTesting public Map<String, ModifiableRootModel> modules = Maps.newHashMap();

  public ModuleEditorImpl(Project project, BlazeImportSettings importSettings) {
    this.project = project;
    this.moduleModel = ModuleManager.getInstance(project).getModifiableModel();

    this.imlDirectory = getImlDirectory(importSettings);
    if (!FileAttributeProvider.getInstance().exists(imlDirectory)) {
      if (!imlDirectory.mkdirs()) {
        logger.error("Could not make directory: " + imlDirectory.getPath());
      }
    }
  }

  @Override
  public Module createModule(String moduleName, ModuleType moduleType) {
    Module module = moduleModel.findModuleByName(moduleName);
    if (module == null) {
      File imlFile = new File(imlDirectory, moduleName + ModuleFileType.DOT_DEFAULT_EXTENSION);
      removeImlFile(imlFile);
      module = moduleModel.newModule(imlFile.getPath(), moduleType.getId());
      module.setOption(EXTERNAL_SYSTEM_ID_KEY, EXTERNAL_SYSTEM_ID_VALUE);
    }
    module.setOption(Module.ELEMENT_TYPE, moduleType.getId());

    ModifiableRootModel modifiableModel =
        ModuleRootManager.getInstance(module).getModifiableModel();
    modules.put(module.getName(), modifiableModel);
    modifiableModel.clear();
    modifiableModel.inheritSdk();
    CompilerModuleExtension compilerSettings =
        modifiableModel.getModuleExtension(CompilerModuleExtension.class);
    if (compilerSettings != null) {
      compilerSettings.inheritCompilerOutputPath(false);
    }

    return module;
  }

  @Override
  public ModifiableRootModel editModule(Module module) {
    return modules.get(module.getName());
  }

  @Override
  @Nullable
  public Module findModule(String moduleName) {
    return moduleModel.findModuleByName(moduleName);
  }

  public void commitWithGc(BlazeContext context) {
    List<Module> orphanModules = Lists.newArrayList();
    for (Module module : ModuleManager.getInstance(project).getModules()) {
      if (!modules.containsKey(module.getName())) {
        orphanModules.add(module);
      }
    }
    if (orphanModules.size() > 0) {
      context.output(
          PrintOutput.log(String.format("Removing %d dead modules", orphanModules.size())));
      for (Module module : orphanModules) {
        if (module.isDisposed()) {
          continue;
        }
        moduleModel.disposeModule(module);
        File imlFile = new File(module.getModuleFilePath());
        removeImlFile(imlFile);
      }
    }

    context.output(PrintOutput.log(String.format("Workspace has %s modules", modules.size())));

    commit();
  }

  @Override
  public void commit() {
    ModifiableModelCommitter.multiCommit(modules.values(), moduleModel);
  }

  private File getImlDirectory(BlazeImportSettings importSettings) {
    return new File(BlazeDataStorage.getProjectDataDir(importSettings), "modules");
  }

  // Delete using the virtual file to ensure that IntelliJ properly updates its index.
  // Otherwise, it is possible for IntelliJ to read the
  // old IML file from its index and behave unpredictably
  // (like failing to save the new IML files to disk).
  private static void removeImlFile(final File imlFile) {
    final VirtualFile imlVirtualFile = VfsUtil.findFileByIoFile(imlFile, true);
    if (imlVirtualFile != null && imlVirtualFile.exists()) {
      ApplicationManager.getApplication()
          .runWriteAction(
              new Runnable() {
                @Override
                public void run() {
                  try {
                    imlVirtualFile.delete(this);
                  } catch (IOException e) {
                    logger.warn(
                        String.format(
                            "Could not delete file: %s, will try to continue anyway.",
                            imlVirtualFile.getPath()),
                        e);
                  }
                }
              });
    }
  }
}
