/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you 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 org.apache.calcite.plan.volcano;

import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.metadata.Metadata;
import org.apache.calcite.rel.metadata.MetadataDef;
import org.apache.calcite.rel.metadata.MetadataHandler;
import org.apache.calcite.rel.metadata.RelMetadataProvider;
import org.apache.calcite.rel.metadata.UnboundMetadata;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;

import org.checkerframework.checker.nullness.qual.Nullable;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Objects;

/**
 * VolcanoRelMetadataProvider implements the {@link RelMetadataProvider}
 * interface by combining metadata from the rels making up an equivalence class.
 */
@Deprecated // to be removed before 2.0
public class VolcanoRelMetadataProvider implements RelMetadataProvider {
  //~ Methods ----------------------------------------------------------------

  @Override public boolean equals(@Nullable Object obj) {
    return obj instanceof VolcanoRelMetadataProvider;
  }

  @Override public int hashCode() {
    return 103;
  }

  @Deprecated // to be removed before 2.0
  @Override public <@Nullable M extends @Nullable Metadata> @Nullable UnboundMetadata<M> apply(
      Class<? extends RelNode> relClass,
      final Class<? extends M> metadataClass) {
    if (relClass != RelSubset.class) {
      // let someone else further down the chain sort it out
      return null;
    }

    return (rel, mq) -> {
      final RelSubset subset = (RelSubset) rel;
      final RelMetadataProvider provider = Objects.requireNonNull(
          rel.getCluster().getMetadataProvider(),
          "metadataProvider");

      // REVIEW jvs 29-Mar-2006: I'm not sure what the correct precedence
      // should be here.  Letting the current best plan take the first shot is
      // probably the right thing to do for physical estimates such as row
      // count.  Dunno about others, and whether we need a way to
      // discriminate.

      // First, try current best implementation.  If it knows how to answer
      // this query, treat it as the most reliable.
      if (subset.best != null) {
        RelNode best = subset.best;
        final UnboundMetadata<M> function =
            provider.apply(best.getClass(), metadataClass);
        if (function != null) {
          final M metadata = function.bind(best, mq);
          if (metadata != null) {
            return metadata;
          }
        }
      }

      // Otherwise, try rels in same logical equivalence class to see if any
      // of them have a good answer.  We use the full logical equivalence
      // class rather than just the subset because many metadata providers
      // only know about logical metadata.

      // Equivalence classes can get tangled up in interesting ways, so avoid
      // an infinite loop.  REVIEW: There's a chance this will cause us to
      // fail on metadata queries which invoke other queries, e.g.
      // PercentageOriginalRows -> Selectivity.  If we implement caching at
      // this level, we could probably kill two birds with one stone (use
      // presence of pending cache entry to detect re-entrancy at the correct
      // granularity).
      if (subset.set.inMetadataQuery) {
        return null;
      }

      subset.set.inMetadataQuery = true;
      try {
        for (RelNode relCandidate : subset.set.rels) {
          final UnboundMetadata<M> function =
              provider.apply(relCandidate.getClass(), metadataClass);
          if (function != null) {
            final M result = function.bind(relCandidate, mq);
            if (result != null) {
              return result;
            }
          }
        }
      } finally {
        subset.set.inMetadataQuery = false;
      }

      // Give up.
      return null;
    };
  }

  @Deprecated
  @Override public <M extends Metadata> Multimap<Method, MetadataHandler<M>> handlers(
      MetadataDef<M> def) {
    return ImmutableMultimap.of();
  }

  @Override public List<MetadataHandler<?>> handlers(
      Class<? extends MetadataHandler<?>> handlerClass) {
    return ImmutableList.of();
  }
}
