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

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.idea.blaze.base.model.BlazeLibrary;
import com.google.idea.blaze.base.model.BlazeProjectData;
import com.google.idea.blaze.base.model.LibraryKey;
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.scope.output.PrintOutput;
import com.google.idea.blaze.base.sync.BlazeSyncPlugin;
import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/** Edits IntelliJ libraries */
public class LibraryEditor {
  private static final Logger logger = Logger.getInstance(LibraryEditor.class);

  public static void updateProjectLibraries(
      Project project,
      BlazeContext context,
      BlazeProjectData blazeProjectData,
      Collection<BlazeLibrary> libraries) {
    Set<LibraryKey> intelliJLibraryState = Sets.newHashSet();
    for (Library library : ProjectLibraryTable.getInstance(project).getLibraries()) {
      String name = library.getName();
      if (name != null) {
        intelliJLibraryState.add(LibraryKey.fromIntelliJLibraryName(name));
      }
    }
    context.output(PrintOutput.log(String.format("Workspace has %d libraries", libraries.size())));

    LibraryTable libraryTable = ProjectLibraryTable.getInstance(project);
    LibraryTable.ModifiableModel libraryTableModel = libraryTable.getModifiableModel();
    try {
      for (BlazeLibrary library : libraries) {
        updateLibrary(
            project,
            blazeProjectData.artifactLocationDecoder,
            libraryTable,
            libraryTableModel,
            library);
      }

      // Garbage collect unused libraries
      List<LibrarySource> librarySources = Lists.newArrayList();
      for (BlazeSyncPlugin syncPlugin : BlazeSyncPlugin.EP_NAME.getExtensions()) {
        LibrarySource librarySource = syncPlugin.getLibrarySource(blazeProjectData);
        if (librarySource != null) {
          librarySources.add(librarySource);
        }
      }
      Predicate<Library> gcRetentionFilter =
          librarySources
              .stream()
              .map(LibrarySource::getGcRetentionFilter)
              .filter(Objects::nonNull)
              .reduce(Predicate::or)
              .orElse(o -> false);

      Set<LibraryKey> newLibraryKeys =
          libraries.stream().map((blazeLibrary) -> blazeLibrary.key).collect(Collectors.toSet());
      for (LibraryKey libraryKey : intelliJLibraryState) {
        String libraryIntellijName = libraryKey.getIntelliJLibraryName();
        if (!newLibraryKeys.contains(libraryKey)) {
          Library library = libraryTable.getLibraryByName(libraryIntellijName);
          if (!gcRetentionFilter.test(library)) {
            if (library != null) {
              libraryTableModel.removeLibrary(library);
            }
          }
        }
      }
    } finally {
      libraryTableModel.commit();
    }
  }

  public static void updateLibrary(
      Project project,
      ArtifactLocationDecoder artifactLocationDecoder,
      LibraryTable libraryTable,
      LibraryTable.ModifiableModel libraryTableModel,
      BlazeLibrary blazeLibrary) {
    String libraryName = blazeLibrary.key.getIntelliJLibraryName();

    Library library = libraryTable.getLibraryByName(libraryName);
    boolean libraryExists = library != null;
    if (!libraryExists) {
      library = libraryTableModel.createLibrary(libraryName);
    }
    Library.ModifiableModel libraryModel = library.getModifiableModel();
    if (libraryExists) {
      for (String url : libraryModel.getUrls(OrderRootType.CLASSES)) {
        libraryModel.removeRoot(url, OrderRootType.CLASSES);
      }
      for (String url : libraryModel.getUrls(OrderRootType.SOURCES)) {
        libraryModel.removeRoot(url, OrderRootType.SOURCES);
      }
    }
    try {
      blazeLibrary.modifyLibraryModel(project, artifactLocationDecoder, libraryModel);
    } finally {
      libraryModel.commit();
    }
  }

  public static void configureDependencies(
      ModifiableRootModel modifiableRootModel, Collection<BlazeLibrary> libraries) {
    for (BlazeLibrary library : libraries) {
      updateLibraryDependency(modifiableRootModel, library.key);
    }
  }

  private static void updateLibraryDependency(ModifiableRootModel model, LibraryKey libraryKey) {
    LibraryTable libraryTable = ProjectLibraryTable.getInstance(model.getProject());
    Library library = libraryTable.getLibraryByName(libraryKey.getIntelliJLibraryName());
    if (library == null) {
      logger.error(
          "Library missing: "
              + libraryKey.getIntelliJLibraryName()
              + ". Please resync project to resolve.");
      return;
    }
    model.addLibraryEntry(library);
  }
}
