/*
 * Copyright 2000-2013 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 org.jetbrains.idea.maven.importing;

import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.module.ModifiableModuleModel;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.impl.ModuleOrderEntryImpl;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.util.Processor;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.model.MavenArtifact;
import org.jetbrains.idea.maven.model.MavenConstants;
import org.jetbrains.idea.maven.project.MavenProject;
import org.jetbrains.idea.maven.project.MavenProjectsManager;
import org.jetbrains.idea.maven.utils.Path;
import org.jetbrains.idea.maven.utils.Url;
import org.jetbrains.jps.model.JpsElement;
import org.jetbrains.jps.model.java.JavaSourceRootType;
import org.jetbrains.jps.model.java.JpsJavaExtensionService;
import org.jetbrains.jps.model.module.JpsModuleSourceRootType;

import java.io.File;
import java.util.Arrays;
import java.util.Set;

public class MavenRootModelAdapter {

  private final MavenProject myMavenProject;
  private final ModifiableModuleModel myModuleModel;
  private final ModifiableRootModel myRootModel;

  private final MavenSourceFoldersModuleExtension myRootModelModuleExtension;

  private final Set<String> myOrderEntriesBeforeJdk = new THashSet<String>();

  public MavenRootModelAdapter(@NotNull MavenProject p, @NotNull Module module, final MavenModifiableModelsProvider rootModelsProvider) {
    myMavenProject = p;
    myModuleModel = rootModelsProvider.getModuleModel();
    myRootModel = rootModelsProvider.getRootModel(module);

    myRootModelModuleExtension = myRootModel.getModuleExtension(MavenSourceFoldersModuleExtension.class);
    myRootModelModuleExtension.init(module, myRootModel);
  }

  public void init(boolean isNewlyCreatedModule) {
    setupInitialValues(isNewlyCreatedModule);
    initContentRoots();
    initOrderEntries();
  }

  private void setupInitialValues(boolean newlyCreatedModule) {
    if (newlyCreatedModule || myRootModel.getSdk() == null) {
      myRootModel.inheritSdk();
    }
    if (newlyCreatedModule) {
      getCompilerExtension().setExcludeOutput(true);
    }
  }

  private void initContentRoots() {
    Url url = toUrl(myMavenProject.getDirectory());
    if (getContentRootFor(url) != null) return;
    myRootModel.addContentEntry(url.getUrl());
  }

  private ContentEntry getContentRootFor(Url url) {
    for (ContentEntry e : myRootModel.getContentEntries()) {
      if (VfsUtilCore.isEqualOrAncestor(e.getUrl(), url.getUrl())) return e;
    }
    return null;
  }

  private void initOrderEntries() {
    boolean jdkProcessed = false;

    for (OrderEntry e : myRootModel.getOrderEntries()) {
      if (e instanceof ModuleSourceOrderEntry || e instanceof JdkOrderEntry) {
        jdkProcessed = true;
        continue;
      }

      if (e instanceof LibraryOrderEntry) {
        if (!isMavenLibrary(((LibraryOrderEntry)e).getLibrary())) continue;
      }
      if (e instanceof ModuleOrderEntry) {
        Module m = ((ModuleOrderEntry)e).getModule();
        if (m != null && !MavenProjectsManager.getInstance(myRootModel.getProject()).isMavenizedModule(m)) continue;
      }

      if (!jdkProcessed) {
        if (e instanceof ModuleOrderEntry) {
          myOrderEntriesBeforeJdk.add(((ModuleOrderEntry)e).getModuleName());
        }
        else if (e instanceof LibraryOrderEntry) {
          myOrderEntriesBeforeJdk.add(((LibraryOrderEntry)e).getLibraryName());
        }
      }

      myRootModel.removeOrderEntry(e);
    }
  }

  public ModifiableRootModel getRootModel() {
    return myRootModel;
  }

  @NotNull
  public String[] getSourceRootUrls(boolean includingTests) {
    return myRootModelModuleExtension.getSourceRootUrls(includingTests);
  }

  public Module getModule() {
    return myRootModel.getModule();
  }

  public void clearSourceFolders() {
    myRootModelModuleExtension.clearSourceFolders();
  }

  public <P extends JpsElement> void addSourceFolder(String path, final JpsModuleSourceRootType<P> rootType) {
    addSourceFolder(path, rootType, false, rootType.createDefaultProperties());
  }

  public void addGeneratedJavaSourceFolder(String path, JavaSourceRootType rootType) {
    addSourceFolder(path, rootType, true, JpsJavaExtensionService.getInstance().createSourceRootProperties("", true));
  }

  private  <P extends JpsElement> void addSourceFolder(@NotNull String path, final @NotNull JpsModuleSourceRootType<P> rootType, boolean ifNotEmpty,
                                                       final @NotNull P properties) {
    if (ifNotEmpty) {
      String[] childs = new File(toPath(path).getPath()).list();
      if (childs == null || childs.length == 0) return;
    }
    else {
      if (!exists(path)) return;
    }

    Url url = toUrl(path);
    myRootModelModuleExtension.addSourceFolder(url, rootType, properties);
  }

  public boolean hasRegisteredSourceSubfolder(@NotNull File f) {
    String url = toUrl(f.getPath()).getUrl();
    return myRootModelModuleExtension.hasRegisteredSourceSubfolder(url);
  }

  @Nullable
  public SourceFolder getSourceFolder(File folder) {
    String url = toUrl(folder.getPath()).getUrl();
    return myRootModelModuleExtension.getSourceFolder(url);
  }

  public boolean isAlreadyExcluded(File f) {
    String url = toUrl(f.getPath()).getUrl();
    return VfsUtilCore.isUnder(url, Arrays.asList(myRootModel.getExcludeRootUrls()));
  }

  private boolean exists(String path) {
    return new File(toPath(path).getPath()).exists();
  }

  public void addExcludedFolder(String path) {
    unregisterAll(path, true, false);
    Url url = toUrl(path);
    ContentEntry e = getContentRootFor(url);
    if (e == null) return;
    if (e.getUrl().equals(url.getUrl())) return;
    e.addExcludeFolder(url.getUrl());
    if (!Registry.is("ide.hide.excluded.files")) {
      Project project = myRootModel.getProject();
      ChangeListManager.getInstance(project).addDirectoryToIgnoreImplicitly(toPath(path).getPath());
    }
  }

  public void unregisterAll(String path, boolean under, boolean unregisterSources) {
    Url url = toUrl(path);

    for (ContentEntry eachEntry : myRootModel.getContentEntries()) {
      if (unregisterSources) {
        myRootModelModuleExtension.unregisterAll(url, under);
      }

      for (String excludedUrl : eachEntry.getExcludeFolderUrls()) {
        String ancestor = under ? url.getUrl() : excludedUrl;
        String child = under ? excludedUrl : url.getUrl();

        if (VfsUtilCore.isEqualOrAncestor(ancestor, child)) {
          eachEntry.removeExcludeFolder(excludedUrl);
        }
      }
      for (String outputUrl : getCompilerExtension().getOutputRootUrls(true)) {
        String ancestor = under ? url.getUrl() : outputUrl;
        String child = under ? outputUrl : url.getUrl();
        if (VfsUtilCore.isEqualOrAncestor(ancestor, child)) {
          getCompilerExtension().setExcludeOutput(false);
        }
      }
    }
  }

  public boolean hasCollision(String sourceRootPath) {
    Url url = toUrl(sourceRootPath);

    for (ContentEntry eachEntry : myRootModel.getContentEntries()) {
      for (SourceFolder eachFolder : eachEntry.getSourceFolders()) {
        String ancestor = url.getUrl();
        String child = eachFolder.getUrl();
        if (VfsUtilCore.isEqualOrAncestor(ancestor, child) || VfsUtilCore.isEqualOrAncestor(child, ancestor)) {
          return true;
        }
      }

      for (String excludeUrl : eachEntry.getExcludeFolderUrls()) {
        String ancestor = url.getUrl();
        if (VfsUtilCore.isEqualOrAncestor(ancestor, excludeUrl) || VfsUtilCore.isEqualOrAncestor(excludeUrl, ancestor)) {
          return true;
        }
      }
    }

    return false;
  }

  public void useModuleOutput(String production, String test) {
    getCompilerExtension().inheritCompilerOutputPath(false);
    getCompilerExtension().setCompilerOutputPath(toUrl(production).getUrl());
    getCompilerExtension().setCompilerOutputPathForTests(toUrl(test).getUrl());
  }

  private CompilerModuleExtension getCompilerExtension() {
    return myRootModel.getModuleExtension(CompilerModuleExtension.class);
  }

  private Url toUrl(String path) {
    return toPath(path).toUrl();
  }

  public Path toPath(String path) {
    if (!FileUtil.isAbsolute(path)) {
      path = new File(myMavenProject.getDirectory(), path).getPath();
    }
    return new Path(path);
  }

  public void addModuleDependency(@NotNull String moduleName,
                                  @NotNull DependencyScope scope,
                                  boolean testJar) {
    Module m = findModuleByName(moduleName);

    ModuleOrderEntry e;
    if (m != null) {
      e = myRootModel.addModuleOrderEntry(m);
    }
    else {
      AccessToken accessToken = ReadAction.start();
      try {
        e = myRootModel.addInvalidModuleEntry(moduleName);
      }
      finally {
        accessToken.finish();
      }
    }

    e.setScope(scope);
    if (testJar) {
      ((ModuleOrderEntryImpl)e).setProductionOnTestDependency(true);
    }

    if (myOrderEntriesBeforeJdk.contains(moduleName)) {
      moveLastOrderEntryBeforeJdk();
    }
  }

  @Nullable
  public Module findModuleByName(String moduleName) {
    return myModuleModel.findModuleByName(moduleName);
  }

  public void addSystemDependency(MavenArtifact artifact, DependencyScope scope) {
    assert MavenConstants.SCOPE_SYSTEM.equals(artifact.getScope());

    String libraryName = artifact.getLibraryName();

    Library library = myRootModel.getModuleLibraryTable().getLibraryByName(libraryName);
    if (library == null) {
      library = myRootModel.getModuleLibraryTable().createLibrary(libraryName);
    }

    LibraryOrderEntry orderEntry = myRootModel.findLibraryOrderEntry(library);
    assert orderEntry != null;
    orderEntry.setScope(scope);

    Library.ModifiableModel modifiableModel = library.getModifiableModel();
    updateUrl(modifiableModel, OrderRootType.CLASSES, artifact, null, null, true);
    modifiableModel.commit();

    if (myOrderEntriesBeforeJdk.contains(libraryName)) {
      moveLastOrderEntryBeforeJdk();
    }
  }

  public void addLibraryDependency(MavenArtifact artifact,
                                   DependencyScope scope,
                                   MavenModifiableModelsProvider provider,
                                   MavenProject project) {
    assert !MavenConstants.SCOPE_SYSTEM.equals(artifact.getScope()); // System dependencies must be added ad module library, not as project wide library.

    String libraryName = artifact.getLibraryName();

    Library library = provider.getLibraryByName(libraryName);
    if (library == null) {
      library = provider.createLibrary(libraryName);
    }
    Library.ModifiableModel libraryModel = provider.getLibraryModel(library);

    updateUrl(libraryModel, OrderRootType.CLASSES, artifact, null, null, true);
    updateUrl(libraryModel, OrderRootType.SOURCES, artifact, MavenExtraArtifactType.SOURCES, project, false);
    updateUrl(libraryModel, JavadocOrderRootType.getInstance(), artifact, MavenExtraArtifactType.DOCS, project, false);

    LibraryOrderEntry e = myRootModel.addLibraryEntry(library);
    e.setScope(scope);

    if (myOrderEntriesBeforeJdk.contains(libraryName)) {
      moveLastOrderEntryBeforeJdk();
    }
  }

  private void moveLastOrderEntryBeforeJdk() {
    OrderEntry[] entries = myRootModel.getOrderEntries().clone();

    int i = entries.length - 1;
    while (i > 0 && (entries[i - 1] instanceof ModuleSourceOrderEntry || entries[i - 1] instanceof JdkOrderEntry)) {
      OrderEntry e = entries[i - 1];
      entries[i - 1] = entries[i];
      entries[i] = e;
      i--;
    }

    if (i < entries.length) {
      myRootModel.rearrangeOrderEntries(entries);
    }
  }

  private static void updateUrl(Library.ModifiableModel library,
                                OrderRootType type,
                                MavenArtifact artifact,
                                MavenExtraArtifactType artifactType,
                                MavenProject project,
                                boolean clearAll) {
    String classifier = null;
    String extension = null;

    if (artifactType != null) {
      Pair<String, String> result = project.getClassifierAndExtension(artifact, artifactType);
      classifier = result.first;
      extension = result.second;
    }


    String newPath = artifact.getPathForExtraArtifact(classifier, extension);
    String newUrl = VirtualFileManager.constructUrl(JarFileSystem.PROTOCOL, newPath) + JarFileSystem.JAR_SEPARATOR;

    boolean urlExists = false;

    for (String url : library.getUrls(type)) {
      if (newUrl.equals(url)) {
        urlExists = true;
        continue;
      }
      if (clearAll || (isRepositoryUrl(artifact, url) && !url.startsWith(newUrl))) {
        library.removeRoot(url, type);
      }
    }

    if (!urlExists) {
      library.addRoot(newUrl, type);
    }
  }

  private static boolean isRepositoryUrl(MavenArtifact artifact, String url) {
    return url.contains(artifact.getGroupId().replace('.', '/') + '/' + artifact.getArtifactId() + '/' + artifact.getBaseVersion() + '/' + artifact.getArtifactId() + '-');
  }

  public static boolean isChangedByUser(Library library) {
    String[] classRoots = library.getUrls(OrderRootType.CLASSES);
    if (classRoots.length != 1) return true;

    String classes = classRoots[0];

    if (!classes.endsWith("!/")) return true;

    int dotPos = classes.lastIndexOf("/", classes.length() - 2 /* trim ending !/ */);
    if (dotPos == -1) return true;
    String pathToJar = classes.substring(0, dotPos);

    if (hasUserPaths(OrderRootType.SOURCES, library, pathToJar)) return true;
    if (hasUserPaths(JavadocOrderRootType.getInstance(), library, pathToJar)) return true;

    return false;
  }

  private static boolean hasUserPaths(OrderRootType rootType, Library library, String pathToJar) {
    String[] sources = library.getUrls(rootType);
    for (String each : sources) {
      if (!FileUtil.startsWith(each, pathToJar)) return true;
    }
    return false;
  }

  public Library findLibrary(@NotNull final MavenArtifact artifact) {
    final String name = artifact.getLibraryName();
    final Ref<Library> result = Ref.create(null);
    myRootModel.orderEntries().forEachLibrary(new Processor<Library>() {
      @Override
      public boolean process(Library library) {
        if (name.equals(library.getName())) {
          result.set(library);
        }
        return true;
      }
    });
    return result.get();
  }

  @Deprecated // Use artifact.getLibraryName();
  public static String makeLibraryName(@NotNull MavenArtifact artifact) {
    return artifact.getLibraryName();
  }

  public static boolean isMavenLibrary(@Nullable Library library) {
    return library != null && MavenArtifact.isMavenLibrary(library.getName());
  }

  @Nullable
  public static OrderEntry findLibraryEntry(@NotNull Module m, @NotNull MavenArtifact artifact) {
    String name = artifact.getLibraryName();
    for (OrderEntry each : ModuleRootManager.getInstance(m).getOrderEntries()) {
      if (each instanceof LibraryOrderEntry && name.equals(((LibraryOrderEntry)each).getLibraryName())) {
        return each;
      }
    }
    return null;
  }

  @Nullable
  public static MavenArtifact findArtifact(@NotNull MavenProject project, @Nullable Library library) {
    if (library == null) return null;

    String name = library.getName();

    if (!MavenArtifact.isMavenLibrary(name)) return null;

    for (MavenArtifact each : project.getDependencies()) {
      if (each.getLibraryName().equals(name)) return each;
    }
    return null;
  }

  public void setLanguageLevel(LanguageLevel level) {
    try {
      myRootModel.getModuleExtension(LanguageLevelModuleExtension.class).setLanguageLevel(level);
    }
    catch (IllegalArgumentException e) {
      //bad value was stored
    }
  }
}
