// Copyright 2023 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.devtools.build.lib.bazel.bzlmod;

import static com.google.devtools.build.lib.bazel.bzlmod.GsonTypeAdapterUtil.LOCKFILE_GSON;
import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.collect.ImmutableMap;
import com.google.common.eventbus.Subscribe;
import com.google.common.flogger.GoogleLogger;
import com.google.devtools.build.lib.bazel.repository.RepositoryOptions;
import com.google.devtools.build.lib.bazel.repository.RepositoryOptions.LockfileMode;
import com.google.devtools.build.lib.cmdline.LabelConstants;
import com.google.devtools.build.lib.runtime.BlazeModule;
import com.google.devtools.build.lib.runtime.CommandEnvironment;
import com.google.devtools.build.lib.util.AbruptExitException;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.Root;
import com.google.devtools.build.lib.vfs.RootedPath;
import com.google.gson.JsonSyntaxException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;

/**
 * Module collecting Bazel module and module extensions resolution results and updating the
 * lockfile.
 */
public class BazelLockFileModule extends BlazeModule {

  private Path workspaceRoot;
  @Nullable private BazelModuleResolutionEvent moduleResolutionEvent;
  private final List<ModuleExtensionResolutionEvent> extensionResolutionEvents = new ArrayList<>();

  private static final GoogleLogger logger = GoogleLogger.forEnclosingClass();

  @Override
  public void beforeCommand(CommandEnvironment env) {
    workspaceRoot = env.getWorkspace();
    RepositoryOptions options = env.getOptions().getOptions(RepositoryOptions.class);
    if (options.lockfileMode.equals(LockfileMode.UPDATE)) {
      env.getEventBus().register(this);
    }
  }

  @Override
  public void afterCommand() throws AbruptExitException {
    if (moduleResolutionEvent == null && extensionResolutionEvents.isEmpty()) {
      return; // nothing changed, do nothing!
    }

    RootedPath lockfilePath =
        RootedPath.toRootedPath(Root.fromPath(workspaceRoot), LabelConstants.MODULE_LOCKFILE_NAME);

    // Create an updated version of the lockfile with the events updates
    BazelLockFileValue lockfile;
    if (moduleResolutionEvent != null) {
      lockfile = moduleResolutionEvent.getLockfileValue();
    } else {
      // Read the existing lockfile (if none exists, will get an empty lockfile value)
      try {
        lockfile = BazelLockFileFunction.getLockfileValue(lockfilePath);
      } catch (IOException | JsonSyntaxException | NullPointerException e) {
        logger.atSevere().withCause(e).log(
            "Failed to read and parse the MODULE.bazel.lock file with error: %s."
                + " Try deleting it and rerun the build.",
            e.getMessage());
        return;
      }
    }
    lockfile =
        lockfile.toBuilder()
            .setModuleExtensions(combineModuleExtensions(lockfile.getModuleExtensions()))
            .build();

    // Write the new value to the file
    updateLockfile(lockfilePath, lockfile);
    this.moduleResolutionEvent = null;
    this.extensionResolutionEvents.clear();
  }

  /**
   * Combines the old extensions stored in the lockfile -that are still used- with the new
   * extensions from the events (if any)
   *
   * @param oldModuleExtensions Module extensions stored in the current lockfile
   */
  private ImmutableMap<ModuleExtensionId, LockFileModuleExtension> combineModuleExtensions(
      ImmutableMap<ModuleExtensionId, LockFileModuleExtension> oldModuleExtensions) {
    ImmutableMap.Builder<ModuleExtensionId, LockFileModuleExtension> updatedExtensionMap =
        ImmutableMap.builder();

    // This event being null means that no changes occurred to the usages of the stored extensions,
    // hence no changes to any module resulted in re-running resolution. So we can just add all the
    // old stored extensions. Otherwise, check the usage of each one.
    if (moduleResolutionEvent == null) {
      updatedExtensionMap.putAll(oldModuleExtensions);
    } else {
      // Add the old extensions (stored in the lockfile) only if it still has a usage somewhere
      for (Map.Entry<ModuleExtensionId, LockFileModuleExtension> extensionEntry :
          oldModuleExtensions.entrySet()) {
        if (moduleResolutionEvent.getExtensionUsagesById().containsRow(extensionEntry.getKey())) {
          updatedExtensionMap.put(extensionEntry);
        }
      }
    }

    // Add the new resolved extensions
    for (ModuleExtensionResolutionEvent extensionEvent : extensionResolutionEvents) {
      updatedExtensionMap.put(extensionEvent.getExtensionId(), extensionEvent.getModuleExtension());
    }
    return updatedExtensionMap.buildKeepingLast();
  }

  /**
   * Updates the data stored in the lockfile (MODULE.bazel.lock)
   *
   * @param lockfilePath Rooted path to lockfile
   * @param updatedLockfile The updated lockfile data to save
   */
  public static void updateLockfile(RootedPath lockfilePath, BazelLockFileValue updatedLockfile) {
    try {
      FileSystemUtils.writeContent(
          lockfilePath.asPath(), UTF_8, LOCKFILE_GSON.toJson(updatedLockfile));
    } catch (IOException e) {
      logger.atSevere().withCause(e).log(
          "Error while updating MODULE.bazel.lock file: %s", e.getMessage());
    }
  }

  @Subscribe
  public void bazelModuleResolved(BazelModuleResolutionEvent moduleResolutionEvent) {
    this.moduleResolutionEvent = moduleResolutionEvent;
  }

  @Subscribe
  public void moduleExtensionResolved(ModuleExtensionResolutionEvent extensionResolutionEvent) {
    this.extensionResolutionEvents.add(extensionResolutionEvent);
  }
}
