// 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.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.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 {

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

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

  public Type getType() {
    return type;
  }

  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;
    }
  }

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

  /**
   * 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.");
    }
  }
}
