// Copyright 2022 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.sandbox;

import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableSet;
import com.google.common.flogger.GoogleLogger;
import com.google.common.io.Files;
import com.google.devtools.build.lib.util.OS;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Nullable;

/** This class manages cgroups directories for memory-limiting sandboxed processes. */
public abstract class CgroupsInfo implements Cgroup {

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

  /**
   * A regexp that matches cgroups entries in {@code /proc/mounts}.
   *
   * <p>Group 1 is empty (cgroups v1) or '2' (cgroups v2) Group 2 is the mount point. Group 3 is the
   * options, which for v1 includes which hierarchies are mounted here.
   */
  private static final Pattern CGROUPS_MOUNT_PATTERN =
      Pattern.compile("^cgroup(|2)\\s+(\\S*)\\s+cgroup2?\\s+(\\S*).*");

  private static final String PROC_SELF_MOUNTS_PATH = "/proc/self/mounts";
  private static final String PROC_SELF_CGROUP_PATH = "/proc/self/cgroup";

  private static final CgroupsInfo rootCgroup = getRootCgroup(new File(PROC_SELF_MOUNTS_PATH));

  private static final Supplier<CgroupsInfo> blazeSpawnsCgroupSupplier =
      Suppliers.memoize(CgroupsInfo::createBlazeSpawnsCgroup);

  /** Returns whether the local machine supports cgroups. */
  public static boolean isSupported() {
    return OS.getCurrent() == OS.LINUX && getBlazeSpawnsCgroup().canWrite();
  }

  /**
   * Returns an instance of the root cgroup of the hierarchy, {@link InvalidCgroupsInfo} if invalid.
   *
   * <p>For v1, we only care about the memory hierarchy.
   *
   * @param procMountsFile the /proc/self/mounts file.
   */
  @VisibleForTesting
  static CgroupsInfo getRootCgroup(File procMountsFile) {
    if (OS.getCurrent() != OS.LINUX) {
      return new InvalidCgroupsInfo(
          Type.ROOT, /* version= */ null, "Croups is not supported on non-linux environments.");
    }

    List<String> procMountsContents;
    try {
      procMountsContents = Files.readLines(procMountsFile, UTF_8);
    } catch (IOException e) {
      return new InvalidCgroupsInfo(Type.ROOT, /* version= */ null, e);
    }
    File v1RootDir = null;
    File v2RootDir = null;
    for (String s : procMountsContents) {
      Matcher m = CGROUPS_MOUNT_PATTERN.matcher(s);
      if (m.matches()) {
        if (m.group(1).isEmpty()) {
          // v1
          if (m.group(3).contains("memory")) {
            // For now, we only care about the memory cgroup
            v1RootDir = new File(m.group(2));
          }
        } else {
          v2RootDir = new File(m.group(2));
        }
      }
    }
    // If we found the memory controller in v1, we use that, just in case we have a hybrid system
    // where some controllers are v1 and some are v2. It would be harder to detect if v2 has the
    // memory controller
    if (v1RootDir != null) {
      return new CgroupsInfoV1(Type.ROOT, v1RootDir);
    }
    if (v2RootDir != null) {
      return new CgroupsInfoV2(Type.ROOT, v2RootDir);
    }
    return new InvalidCgroupsInfo(
        Type.ROOT,
        /* version= */ null,
        String.format(
            "No cgroups mounted in %s: %s", procMountsFile.getPath(), procMountsContents));
  }

  /**
   * Returns the singleton {@link Type.BLAZE_SPAWNS} cgroup created under the root cgroup, {@link
   * InvalidCgroupsInfo} if invalid.
   */
  public static CgroupsInfo getBlazeSpawnsCgroup() {
    return blazeSpawnsCgroupSupplier.get();
  }

  private static CgroupsInfo createBlazeSpawnsCgroup() {
    if (!rootCgroup.exists()) {
      return new InvalidCgroupsInfo(
          Type.BLAZE_SPAWNS, rootCgroup.getVersion(), "Root cgroup does not exist.");
    }
    return rootCgroup.createBlazeSpawnsCgroup(PROC_SELF_CGROUP_PATH);
  }

  /**
   * Creates a cgroups directory for Blaze to place spawns in.
   *
   * <p>This cgroups directory is created at most once per Blaze instance.
   *
   * @param procSelfCgroupPath path to the <code>/proc/self/cgroup</code> file
   * @return A CgroupsInfo object representing the created cgroup that Blaze can use for
   *     sub-processes (the Blaze process itself is not moved into this directory). If unable to
   *     create, returns an {@link InvalidCgroupsInfo} containing the exception.
   */
  public abstract CgroupsInfo createBlazeSpawnsCgroup(String procSelfCgroupPath);

  /** The version of Cgroups that is currently being used. */
  public enum Version {
    V1,
    V2,
  }

  @Nullable protected Version version;

  /**
   * The types of cgroups relevant to Blaze:
   *
   * <ul>
   *   <li>ROOT: corresponds to the root cgroup where * the hierarchy is mounted at; one of
   *       "/dev/cgroup/{controller}" or "/sys/fs/cgroup".
   *   <li>BLAZE_SPAWNS: corresponds the overarching cgroup that contains children {@link
   *       Type.SPAWN} cgroups.
   *   <li>SPAWN: corresponds to the cgroup for a single spawn - this could be a locally executed
   *       action or a worker process.
   * </ul>
   */
  public enum Type {
    ROOT,
    BLAZE_SPAWNS,
    SPAWN,
  }

  protected Type type;

  /**
   * This is the directory where the cgroup is in, any related files pertaining to limits / resource
   * usage or child cgroups (nested directories) are found here.
   */
  @Nullable protected final File cgroupDir;

  public CgroupsInfo(Type type, @Nullable Version version, @Nullable File cgroupDir) {
    this.version = version;
    this.type = type;
    this.cgroupDir = cgroupDir;
    // Valid.
    if (exists()) {
      logger.atInfo().log(
          "Successfully found / created %s (%s) cgroup at %s", version, type, cgroupDir.getPath());
    }
  }

  /** Returns whether the cgroup at {@code cgroupDir} exists. */
  @Override
  public boolean exists() {
    return cgroupDir != null && cgroupDir.exists() && cgroupDir.isDirectory();
  }

  /** Returns whether Blaze can write to the current cgroup at {@code cgroupDir}. */
  public boolean canWrite() {
    return exists() && cgroupDir.canWrite();
  }

  /** A cgroups directory for this Blaze instance to put sandboxes in. */
  public File getCgroupDir() {
    return cgroupDir;
  }

  @Override
  public ImmutableSet<Path> paths() {
    return ImmutableSet.of(getCgroupDir().toPath());
  }

  @Nullable
  public Version getVersion() {
    return version;
  }

  public Type getType() {
    return type;
  }

  @Override
  public int getMemoryUsageInKb() {
    return 0;
  }

  public int getMemoryUsageInKbFromFile(String filename) {
    try {
      String val = Files.readLines(new File(cgroupDir, filename), UTF_8).get(0);
      return (int) (Long.parseLong(val) / 1024);
    } catch (IOException e) {
      return 0;
    }
  }

  @Override
  public void addProcess(long pid) throws IOException {
    Files.asCharSink(new File(cgroupDir, "cgroup.procs"), UTF_8).write(Long.toString(pid));
  }

  @Override
  public void destroy() {
    getCgroupDir().delete();
  }

  /**
   * Creates a cgroups directory for individual spawns (local / workers).
   *
   * <p>Has to be called from a {@link Type.BLAZE_SPAWNS} cgroup.
   *
   * @param dirName the directory name of the spawn's cgroup.
   * @param memoryLimitMb memory limit in Mb to set on the cgroup. If 0, no limit is set.
   * @return an instance of the spawn's cgroup; if unable to create, returns an {@link
   *     InvalidCgroupsInfo} containing the exception.
   */
  public abstract CgroupsInfo createIndividualSpawnCgroup(String dirName, int memoryLimitMb);

  /**
   * Represents an invalid cgroup so that we can distinguish between whether a cgroup was not meant
   * to be created (null) or if it was attempted but failed.
   */
  public static class InvalidCgroupsInfo extends CgroupsInfo {

    private final Exception exception;

    public InvalidCgroupsInfo(Type type, @Nullable Version version, String errorMessage) {
      super(type, version, null);
      this.exception = new IllegalStateException(errorMessage);
      logger.atInfo().withCause(exception).log("Unable to create cgroup.");
    }

    public InvalidCgroupsInfo(Type type, @Nullable Version version, Exception exception) {
      super(type, version, null);
      logger.atInfo().withCause(exception).log("Unable to create cgroup.");
      this.exception = exception;
    }

    @Override
    public boolean exists() {
      return false;
    }

    @Override
    public boolean canWrite() {
      return false;
    }

    public Exception getException() {
      return exception;
    }

    @Override
    public CgroupsInfo createBlazeSpawnsCgroup(String procSelfCgroupPath) {
      return new InvalidCgroupsInfo(
          Type.BLAZE_SPAWNS,
          getVersion(),
          "Unable to create BLAZE_SPAWNS cgroup from an invalid cgroup.");
    }

    @Override
    public CgroupsInfo createIndividualSpawnCgroup(String dirName, int memoryLimitMb) {
      return new InvalidCgroupsInfo(
          Type.SPAWN, getVersion(), "Unable to create SPAWN cgroup from an invalid cgroup.");
    }
  }
}
