// Copyright 2015 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.rules.cpp;

import com.google.common.collect.Lists;

import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * A list of extra libraries to include in a link.  These are non-C++
 * libraries that are built from inputs gathered from all the dependencies.
 * The dependencies have no way to coordinate, so each one will add an
 * ExtraLinkTimeLibrary to its CcLinkParams.  ExtraLinkTimeLibrary is an
 * interface, and all ExtraLinkTimeLibrary objects of the same class will
 * be gathered together.
 */
public final class ExtraLinkTimeLibraries {
  /**
   * We can have multiple different kinds of lists of libraries to include
   * at link time.  We map from the class type to an actual instance.
   */
  private final Collection<ExtraLinkTimeLibrary> extraLibraries;

  private ExtraLinkTimeLibraries(Collection<ExtraLinkTimeLibrary> extraLibraries) {
    this.extraLibraries = extraLibraries;
  }

  /**
   * Return the set of extra libraries.
   */
  public Collection<ExtraLinkTimeLibrary> getExtraLibraries() {
    return extraLibraries;
  }

  public static final Builder builder() {
    return new Builder();
  }

  /**
   * Builder for {@link ExtraLinkTimeLibraries}.
   */
  public static final class Builder {
    private Map<Class<? extends ExtraLinkTimeLibrary>, ExtraLinkTimeLibrary.Builder> libraries =
          new LinkedHashMap<>();

    private Builder() {
      // Nothing to do.
    }

    /**
     * Build a {@link ExtraLinkTimeLibraries} object.
     */
    public ExtraLinkTimeLibraries build() {
      List<ExtraLinkTimeLibrary> extraLibraries = Lists.newArrayList();
      for (ExtraLinkTimeLibrary.Builder builder : libraries.values()) {
        extraLibraries.add(builder.build());
      }
      return new ExtraLinkTimeLibraries(extraLibraries);
    }

    /**
     * Add a transitive dependency.
     */
    public final Builder addTransitive(ExtraLinkTimeLibraries dep) {
      for (ExtraLinkTimeLibrary depLibrary : dep.getExtraLibraries()) {
        Class<? extends ExtraLinkTimeLibrary> c = depLibrary.getClass();
        if (!libraries.containsKey(c)) {
          libraries.put(c, depLibrary.getBuilder());
        }
        libraries.get(c).addTransitive(depLibrary);
      }
      return this;
    }

    /**
     * Add a single library to build.
     */
    public final Builder add(ExtraLinkTimeLibrary b) {
      Class<? extends ExtraLinkTimeLibrary> c = b.getClass();
      if (!libraries.containsKey(c)) {
        libraries.put(c, b.getBuilder());
      }
      libraries.get(c).addTransitive(b);
      return this;
    }
  }
}
