// 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.runtime.commands;

import static com.google.devtools.build.lib.util.ShallowObjectSizeComputer.getArraySize;
import static com.google.devtools.build.lib.util.ShallowObjectSizeComputer.getShallowSize;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import com.google.devtools.build.lib.collect.CompactImmutableMap;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.util.MemoryAccountant;
import com.google.devtools.build.lib.util.ObjectGraphTraverser.DomainSpecificTraverser;
import com.google.devtools.build.lib.util.ObjectGraphTraverser.Traversal;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;

/** An object traverser that handles common collection classes. */
public class CollectionObjectTraverser
    implements DomainSpecificTraverser, MemoryAccountant.Measurer {
  private static final String NESTEDSET_ARRAY = "Object[] NestedSet";
  private static final Field NESTEDSET_CHILDREN;

  static {
    try {
      NESTEDSET_CHILDREN = NestedSet.class.getDeclaredField("children");
      NESTEDSET_CHILDREN.setAccessible(true);
    } catch (NoSuchFieldException e) {
      throw new IllegalStateException(e);
    }
  }

  @Override
  public long maybeGetShallowSize(Object o) {
    return switch (o) {
      case List<?> l -> getShallowSize(l) + getArraySize(l.size(), Object.class);
      case Set<?> s -> getShallowSize(s) + getArraySize(s.size(), Object.class);
      case Map<?, ?> m ->
          // 32 is an estimate for the per-entry overhead of Map and Multimap
          getShallowSize(m) + m.size() * 32L;
      case Multimap<?, ?> mm -> getShallowSize(mm) + mm.size() * 32L;
      case CompactImmutableMap<?, ?> cim ->
          // For CompactImmutableMap, we ignore OffsetTable: it's interned so it's difficult to
          // assign to any one SkyValue and there aren't supposed to be many of those anyway.
          getShallowSize(cim) + getArraySize(cim.size(), Object.class);

      default -> -1;
    };
  }

  @Override
  @SuppressWarnings({"rawtypes", "unchecked"})
  public boolean maybeTraverse(Object o, Traversal traversal) {
    switch (o) {
      case List<?> l -> {
        traversal.objectFound(l, "List");
        for (Object m : l) {
          traversal.edgeFound(m, null);
        }

        return true;
      }

      case Set<?> s -> {
        traversal.objectFound(s, "Set");
        for (Object m : s) {
          traversal.edgeFound(m, null);
        }

        return true;
      }

      case Map<?, ?> m -> {
        traversal.objectFound(m, "Map");
        for (Map.Entry<?, ?> e : m.entrySet()) {
          traversal.edgeFound(e.getKey(), null);
          traversal.edgeFound(e.getValue(), null);
        }

        return true;
      }

      case Multimap<?, ?> mm -> {
        traversal.objectFound(mm, "Multimap");
        for (Map.Entry<?, ?> e : mm.entries()) {
          traversal.edgeFound(e.getKey(), null);
          traversal.edgeFound(e.getValue(), null);
        }

        return true;
      }

      case CompactImmutableMap cim -> {
        traversal.objectFound(cim, "CompactImmutableMap");
        for (Object k : cim) {
          traversal.edgeFound(k, null);
          traversal.edgeFound(cim.get(k), null);
        }
        return true;
      }

      case NestedSet<?> ns -> {
        traversal.objectFound(ns, "NestedSet");
        Object children;
        try {
          children = NESTEDSET_CHILDREN.get(ns);
        } catch (IllegalArgumentException | IllegalAccessException e) {
          throw new IllegalStateException(e);
        }

        if (children instanceof Object[]) {
          traversal.edgeFound(children, NESTEDSET_ARRAY);
        } else {
          traversal.edgeFound(children, null);
        }

        return true;
      }

      default -> {
        return false;
      }
    }
  }

  @Override
  public boolean admit(Object o) {
    return true;
  }

  @Nullable
  @Override
  public String contextForArrayItem(Object from, String fromContext, Object to) {
    return null;
  }

  @Nullable
  @Override
  public String contextForField(Object from, String fromContext, Field field, Object to) {
    return null;
  }

  @Nullable
  @Override
  public ImmutableSet<String> ignoredFields(Class<?> clazz) {
    return null;
  }
}
