/*
 * 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.beam.runners.direct;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.beam.runners.core.construction.TransformInputs;
import org.apache.beam.sdk.Pipeline;
import org.apache.beam.sdk.runners.AppliedPTransform;
import org.apache.beam.sdk.values.PCollection;
import org.apache.beam.sdk.values.PCollectionView;
import org.apache.beam.sdk.values.PInput;
import org.apache.beam.sdk.values.PValue;
import org.apache.beam.vendor.guava.v26_0_jre.com.google.common.collect.ListMultimap;

/**
 * Methods for interacting with the underlying structure of a {@link Pipeline} that is being
 * executed with the {@link DirectRunner}.
 */
class DirectGraph implements ExecutableGraph<AppliedPTransform<?, ?, ?>, PValue> {
  private final Map<PCollection<?>, AppliedPTransform<?, ?, ?>> producers;
  private final Map<PCollectionView<?>, AppliedPTransform<?, ?, ?>> viewWriters;
  private final ListMultimap<PInput, AppliedPTransform<?, ?, ?>> perElementConsumers;

  private final Set<AppliedPTransform<?, ?, ?>> rootTransforms;
  private final Map<AppliedPTransform<?, ?, ?>, String> stepNames;

  public static DirectGraph create(
      Map<PCollection<?>, AppliedPTransform<?, ?, ?>> producers,
      Map<PCollectionView<?>, AppliedPTransform<?, ?, ?>> viewWriters,
      ListMultimap<PInput, AppliedPTransform<?, ?, ?>> perElementConsumers,
      Set<AppliedPTransform<?, ?, ?>> rootTransforms,
      Map<AppliedPTransform<?, ?, ?>, String> stepNames) {
    return new DirectGraph(producers, viewWriters, perElementConsumers, rootTransforms, stepNames);
  }

  private DirectGraph(
      Map<PCollection<?>, AppliedPTransform<?, ?, ?>> producers,
      Map<PCollectionView<?>, AppliedPTransform<?, ?, ?>> viewWriters,
      ListMultimap<PInput, AppliedPTransform<?, ?, ?>> perElementConsumers,
      Set<AppliedPTransform<?, ?, ?>> rootTransforms,
      Map<AppliedPTransform<?, ?, ?>, String> stepNames) {
    this.producers = producers;
    this.viewWriters = viewWriters;
    this.perElementConsumers = perElementConsumers;
    this.rootTransforms = rootTransforms;
    this.stepNames = stepNames;
  }

  @Override
  public AppliedPTransform<?, ?, ?> getProducer(PValue produced) {
    if (produced instanceof PCollection) {
      return producers.get(produced);
    } else if (produced instanceof PCollectionView) {
      return getWriter((PCollectionView<?>) produced);
    }
    throw new IllegalArgumentException(
        String.format(
            "Unknown %s type %s. Known types: %s and %s",
            PValue.class.getSimpleName(),
            produced.getClass().getName(),
            PCollection.class.getSimpleName(),
            PCollectionView.class.getSimpleName()));
  }

  @Override
  public Collection<PValue> getProduced(AppliedPTransform<?, ?, ?> producer) {
    // TODO: This must only be called on primitive transforms; composites should return empty
    // values.
    return producer.getOutputs().values();
  }

  @Override
  public Collection<PValue> getPerElementInputs(AppliedPTransform<?, ?, ?> transform) {
    // TODO: Make this actually track this type of edge, because this isn't quite the right
    // generic possibility, but is for ParDos
    return TransformInputs.nonAdditionalInputs(transform);
  }

  private AppliedPTransform<?, ?, ?> getWriter(PCollectionView<?> view) {
    return viewWriters.get(view);
  }

  @Override
  public List<AppliedPTransform<?, ?, ?>> getPerElementConsumers(PValue consumed) {
    return perElementConsumers.get(consumed);
  }

  @Override
  public Set<AppliedPTransform<?, ?, ?>> getRootTransforms() {
    return rootTransforms;
  }

  @Override
  public Collection<AppliedPTransform<?, ?, ?>> getExecutables() {
    return stepNames.keySet();
  }

  Set<PCollectionView<?>> getViews() {
    return viewWriters.keySet();
  }

  String getStepName(AppliedPTransform<?, ?, ?> step) {
    return stepNames.get(step);
  }
}
