// Copyright 2024 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 com.google.common.base.Preconditions.checkArgument;
import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.io.Files;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.annotation.Nullable;

/** Represents a v2 cgroup. */
public class CgroupsInfoV2 extends CgroupsInfo {

  public CgroupsInfoV2(Type type, @Nullable File cgroupDir) {
    super(type, Version.V2, cgroupDir);
  }

  @Override
  public CgroupsInfo createBlazeSpawnsCgroup(String procSelfCgroupPath) {
    checkArgument(
        type == Type.ROOT, "Should only be creating the Blaze spawns cgroup from the root cgroup.");
    File blazeProcessCgroupDir;
    File blazeSpawnsDir;
    try {
      blazeProcessCgroupDir = getBlazeProcessCgroupDir(cgroupDir, procSelfCgroupPath);
      // In cgroups v2, we need to step back from the leaf node to make a further hierarchy.
      blazeSpawnsDir =
          new File(
              blazeProcessCgroupDir.getParentFile(),
              "blaze_" + ProcessHandle.current().pid() + "_spawns.slice");
      blazeSpawnsDir.mkdirs();
      blazeSpawnsDir.deleteOnExit();
      setSubtreeControllers(blazeSpawnsDir);
    } catch (Exception e) {
      return new InvalidCgroupsInfo(Type.BLAZE_SPAWNS, getVersion(), e);
    }

    return new CgroupsInfoV2(Type.BLAZE_SPAWNS, blazeSpawnsDir);
  }

  @Override
  public CgroupsInfo createIndividualSpawnCgroup(String dirName, int memoryLimitMb) {
    checkArgument(
        type == Type.BLAZE_SPAWNS,
        "Should only be creating the individual spawn's cgroup from the Blaze spawns cgroup.");
    if (!canWrite()) {
      return new InvalidCgroupsInfo(
          Type.SPAWN,
          getVersion(),
          String.format("Cgroup %s is invalid, unable to create spawn's cgroup here.", cgroupDir));
    }
    File spawnCgroupDir = new File(cgroupDir, dirName + ".scope");
    spawnCgroupDir.mkdirs();
    spawnCgroupDir.deleteOnExit();
    try {
      if (memoryLimitMb > 0) {
        // In cgroups v2, we need to propagate the controllers into new subdirs.
        Files.asCharSink(new File(spawnCgroupDir, "memory.oom.group"), UTF_8).write("1\n");
        Files.asCharSink(new File(spawnCgroupDir, "memory.max"), UTF_8)
            .write(Long.toString(memoryLimitMb * 1024L * 1024L));
      }
    } catch (Exception e) {
      return new InvalidCgroupsInfo(Type.SPAWN, getVersion(), e);
    }
    return new CgroupsInfoV2(Type.SPAWN, spawnCgroupDir);
  }

  @Override
  public int getMemoryUsageInKb() {
    return getMemoryUsageInKbFromFile("memory.current");
  }

  /**
   * Returns the path to the cgroup containing the Blaze process.
   *
   * <p>In v2, there is only one entry, and it looks something like this:
   *
   * <pre>
   * 0::/user.slice/user-123.slice/session-1.scope
   * </pre>
   *
   * @param mountPoint the directory where the cgroup hierarchy is mounted.
   * @param procSelfCgroupPath path for the /proc/self/cgroup file.
   * @throws IOException if there are errors reading the given procs cgroup file.
   */
  private static File getBlazeProcessCgroupDir(File mountPoint, String procSelfCgroupPath)
      throws IOException {
    List<String> contents = Files.readLines(new File(procSelfCgroupPath), UTF_8);
    if (contents.isEmpty()) {
      throw new IllegalStateException(
          "Found no memory cgroup entries in '" + procSelfCgroupPath + "'");
    }
    List<String> parts = Splitter.on(":").limit(3).splitToList(contents.get(0));
    return new File(mountPoint, parts.get(2));
  }

  /**
   * Sets the subtree controllers we need. This also checks that the controllers are available.
   *
   * @param blazeDir A directory in the cgroups hierarchy.
   * @throws IOException If reading or writing the {@code cgroup.controllers} or {@code
   *     cgroup.subtree_control} file fails.
   * @throws IllegalStateException if the {@code memory} and {code pids} controllers are either not
   *     available or cannot be set for subtrees.
   */
  private static void setSubtreeControllers(File blazeDir) throws IOException {
    var controllers =
        Joiner.on(' ').join(Files.readLines(new File(blazeDir, "cgroup.controllers"), UTF_8));
    if (!(controllers.contains("memory") && controllers.contains("pids"))) {
      throw new IllegalStateException(
          String.format(
              "Required controllers 'memory' and 'pids' not found in %s/cgroup.controllers",
              blazeDir));
    }
    var subtreeControllers =
        Joiner.on(' ').join(Files.readLines(new File(blazeDir, "cgroup.subtree_control"), UTF_8));
    if (!subtreeControllers.contains("memory") || !subtreeControllers.contains("pids")) {
      Files.asCharSink(new File(blazeDir, "cgroup.subtree_control"), UTF_8)
          .write("+memory +pids\n");
    }
  }
}
