/*
 * Copyright 2000-2012 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.platform.templates;

import com.intellij.execution.RunManager;
import com.intellij.execution.configurations.ModuleBasedConfiguration;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.ide.fileTemplates.FileTemplateManager;
import com.intellij.ide.fileTemplates.FileTemplateUtil;
import com.intellij.ide.util.newProjectWizard.modes.ImportImlMode;
import com.intellij.ide.util.projectWizard.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.module.*;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ex.ProjectManagerEx;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.NullableComputable;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.util.io.StreamUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.RefreshQueue;
import com.intellij.platform.templates.github.ZipUtil;
import com.intellij.util.NullableFunction;
import com.intellij.util.containers.ContainerUtil;
import org.jdom.JDOMException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Properties;
import java.util.zip.ZipInputStream;

/**
* @author Dmitry Avdeev
*         Date: 10/19/12
*/
public class TemplateModuleBuilder extends ModuleBuilder {

  public static final String UTF_8 = "UTF-8";

  private final ModuleType myType;
  private List<WizardInputField> myAdditionalFields;
  private ArchivedProjectTemplate myTemplate;
  private boolean myProjectMode;

  public TemplateModuleBuilder(ArchivedProjectTemplate template, ModuleType moduleType, List<WizardInputField> additionalFields) {
    myTemplate = template;
    myType = moduleType;
    myAdditionalFields = additionalFields;
  }

  @Override
  public void setupRootModel(ModifiableRootModel modifiableRootModel) throws ConfigurationException {

  }

  @Override
  public ModuleWizardStep[] createWizardSteps(@NotNull WizardContext wizardContext, @NotNull ModulesProvider modulesProvider) {
    ModuleBuilder builder = myType.createModuleBuilder();
    return builder.createWizardSteps(wizardContext, modulesProvider);
  }

  @Override
  protected List<WizardInputField> getAdditionalFields() {
    return myAdditionalFields;
  }

  @Override
  public Module commitModule(@NotNull final Project project, ModifiableModuleModel model) {
    if (myProjectMode) {
      final Module[] modules = ModuleManager.getInstance(project).getModules();
      if (modules.length > 0) {
        final Module module = modules[0];
        ApplicationManager.getApplication().runWriteAction(new Runnable() {
          @Override
          public void run() {
            try {
              setupModule(module);
            }
            catch (ConfigurationException e) {
              LOG.error(e);
            }
          }
        });

        StartupManager.getInstance(project).registerPostStartupActivity(new Runnable() {
          @Override
          public void run() {
            ApplicationManager.getApplication().runWriteAction(new Runnable() {
              @Override
              public void run() {
                try {
                  ModifiableModuleModel modifiableModuleModel = ModuleManager.getInstance(project).getModifiableModel();
                  modifiableModuleModel.renameModule(module, module.getProject().getName());
                  modifiableModuleModel.commit();
                  fixModuleName(module);
                }
                catch (ModuleWithNameAlreadyExists exists) {
                  // do nothing
                }
              }
            });
          }
        });
        return module;
      }
      return null;
    }
    else {
      return super.commitModule(project, model);
    }
  }

  @Nullable
  @Override
  public String getBuilderId() {
    return myTemplate.getName();
  }

  @Override
  public ModuleType getModuleType() {
    return myType;
  }

  @Override
  public Icon getNodeIcon() {
    return myTemplate.getIcon();
  }

  @Override
  public boolean isTemplateBased() {
    return true;
  }

  @NotNull
  @Override
  public Module createModule(@NotNull ModifiableModuleModel moduleModel)
    throws InvalidDataException, IOException, ModuleWithNameAlreadyExists, JDOMException, ConfigurationException {
    final String path = getContentEntryPath();
    final ExistingModuleLoader loader = ImportImlMode.setUpLoader(getModuleFilePath());
    unzip(loader.getName(), path, true);
    Module module = loader.createModule(moduleModel);
    if (myProjectMode) {
      moduleModel.renameModule(module, module.getProject().getName());
    }
    fixModuleName(module);
    return module;
  }

  private void fixModuleName(Module module) {
    List<RunConfiguration> configurations = RunManager.getInstance(module.getProject()).getAllConfigurationsList();
    for (RunConfiguration configuration : configurations) {
      if (configuration instanceof ModuleBasedConfiguration) {
        ((ModuleBasedConfiguration)configuration).getConfigurationModule().setModule(module);
      }
    }
    ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
    for (WizardInputField field : myAdditionalFields) {
      ProjectTemplateParameterFactory factory = WizardInputField.getFactoryById(field.getId());
      factory.applyResult(field.getValue(), model);
    }
    model.commit();
  }

  private WizardInputField getBasePackageField() {
    for (WizardInputField field : getAdditionalFields()) {
      if (ProjectTemplateParameterFactory.IJ_BASE_PACKAGE.equals(field.getId())) {
        return field;
      }
    }
    return null;
  }

  private void unzip(final @Nullable String projectName, String path, final boolean moduleMode) {
    File dir = new File(path);
    ZipInputStream zipInputStream = null;
    final WizardInputField basePackage = getBasePackageField();
    try {
      zipInputStream = myTemplate.getStream();
      NullableFunction<String, String> pathConvertor = new NullableFunction<String, String>() {
        @Nullable
        @Override
        public String fun(String path) {
          if (moduleMode && path.contains(Project.DIRECTORY_STORE_FOLDER)) return null;
          if (basePackage != null) {
            return path.replace(getPathFragment(basePackage.getDefaultValue()), getPathFragment(basePackage.getValue()));
          }
          return path;
        }
      };
      ZipUtil.unzip(ProgressManager.getInstance().getProgressIndicator(), dir, zipInputStream, pathConvertor, new ZipUtil.ContentProcessor() {
        @Override
        public byte[] processContent(byte[] content, File file) throws IOException {
          FileType fileType = FileTypeManager.getInstance().getFileTypeByExtension(FileUtilRt.getExtension(file.getName()));
          return fileType.isBinary() ? content : processTemplates(projectName, new String(content), file);
        }
      }, true);
      String iml = ContainerUtil.find(dir.list(), new Condition<String>() {
        @Override
        public boolean value(String s) {
          return s.endsWith(".iml");
        }
      });
      if (moduleMode) {
        File from = new File(path, iml);
        File to = new File(getModuleFilePath());
        if (!from.renameTo(to)) {
          throw new IOException("Can't rename " + from + " to " + to);
        }
      }
      VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(dir);
      if (virtualFile == null) {
        throw new IOException("Can't find " + dir);
      }
      RefreshQueue.getInstance().refresh(false, true, null, virtualFile);
    }
    catch (IOException e) {
      throw new RuntimeException(e);
    }
    finally {
      StreamUtil.closeStream(zipInputStream);
    }
  }

  private static String getPathFragment(String value) {
    return "/" + value.replace('.', '/') + "/";
  }

  @SuppressWarnings("UseOfPropertiesAsHashtable")
  @Nullable
  private byte[] processTemplates(@Nullable String projectName, String content, File file) throws IOException {
    for (WizardInputField field : myAdditionalFields) {
      if (!field.acceptFile(file)) {
        return null;
      }
    }
    Properties properties = FileTemplateManager.getInstance().getDefaultProperties();
    for (WizardInputField field : myAdditionalFields) {
      properties.putAll(field.getValues());
    }
    if (projectName != null) {
      properties.put(ProjectTemplateParameterFactory.IJ_PROJECT_NAME, projectName);
    }
    String merged = FileTemplateUtil.mergeTemplate(properties, content, true);
    return merged.replace("\\$", "$").replace("\\#", "#").getBytes(UTF_8);
  }

  @Nullable
  @Override
  public Project createProject(String name, final String path) {
    myProjectMode = true;
    unzip(name, path, false);
    return ApplicationManager.getApplication().runWriteAction(new NullableComputable<Project>() {
      @Nullable
      @Override
      public Project compute() {
        try {
          return ProjectManagerEx.getInstanceEx().convertAndLoadProject(path);
        }
        catch (IOException e) {
          LOG.error(e);
          return null;
        }
      }
    });
  }

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