/*
 * Copyright 2014-present Facebook, Inc.
 *
 * 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.facebook.buck.python;

import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.rules.RuleKey;
import com.facebook.buck.rules.RuleKeyAppendable;
import com.facebook.buck.rules.SourcePath;
import com.facebook.buck.util.HumanReadableException;
import com.facebook.buck.util.immutables.BuckStyleImmutable;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables;

import org.immutables.value.Value;

import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;

@Value.Immutable(builder = false)
@BuckStyleImmutable
public abstract class PythonPackageComponents implements RuleKeyAppendable {

  // Python modules as map of their module name to location of the source.
  @Value.Parameter
  public abstract Map<Path, SourcePath> getModules();

  // Resources to include in the package.
  @Value.Parameter
  public abstract Map<Path, SourcePath> getResources();

  // Native libraries to include in the package.
  @Value.Parameter
  public abstract Map<Path, SourcePath> getNativeLibraries();

  @Override
  public final RuleKey.Builder appendToRuleKey(RuleKey.Builder builder, String key) {
    // Hash all the input components here so we can detect changes in both input file content
    // and module name mappings.
    // TODO(agallagher): Change the types of these fields from Map to SortedMap so that we don't
    // have to do all this weird stuff to ensure the key is stable. Please update
    // getInputsToCompareToOutput() as well once this is fixed.
    for (ImmutableMap.Entry<String, Map<Path, SourcePath>> part : ImmutableMap.of(
        "module", getModules(),
        "resource", getResources(),
        "nativeLibraries", getNativeLibraries()).entrySet()) {
      for (Path name : ImmutableSortedSet.copyOf(part.getValue().keySet())) {
        builder.setReflectively(part.getKey() + ":" + name, part.getValue().get(name));
      }
    }

    return builder;
  }

  public Iterable<SourcePath> getInputsToCompareToOutput() {
    return Iterables.<SourcePath>concat(
        ImmutableSortedSet.copyOf(getModules().values()),
        ImmutableSortedSet.copyOf(getResources().values()),
        ImmutableSortedSet.copyOf(getNativeLibraries().values()));
  }

  /**
   * A helper class to construct a PythonPackageComponents instance which
   * throws human readable error messages on duplicates.
   */
  public static class Builder {

    // A description of the entity that is building this PythonPackageComponents instance.
    private final BuildTarget owner;

    // The actual maps holding the components.
    private final ImmutableMap.Builder<Path, SourcePath> modules = ImmutableMap.builder();
    private final ImmutableMap.Builder<Path, SourcePath> resources = ImmutableMap.builder();
    private final ImmutableMap.Builder<Path, SourcePath> nativeLibraries = ImmutableMap.builder();

    // Bookkeeping used to for error handling in the presence of duplicate
    // entries.  These data structures map the components named above to the
    // entities that provided them.
    private final Map<Path, BuildTarget> moduleSources = new HashMap<>();
    private final Map<Path, BuildTarget> resourceSources = new HashMap<>();
    private final Map<Path, BuildTarget> nativeLibrarySources = new HashMap<>();

    public Builder(BuildTarget owner) {
      this.owner = owner;
    }

    private HumanReadableException createDuplicateError(
        String type,
        Path destination,
        BuildTarget sourceA,
        BuildTarget sourceB) {
      return new HumanReadableException(
          "%s: found duplicate entries for %s %s when creating python package (%s and %s)",
          owner, type, destination, sourceA, sourceB);
    }

    private Builder add(
        String type,
        ImmutableMap.Builder<Path, SourcePath> builder,
        Map<Path, BuildTarget> sourceDescs,
        Path destination,
        SourcePath source,
        BuildTarget sourceDesc) {
      BuildTarget existing = sourceDescs.get(destination);
      if (existing != null) {
        throw createDuplicateError(type, destination, sourceDesc, existing);
      }
      builder.put(destination, source);
      sourceDescs.put(destination, sourceDesc);
      return this;
    }

    private Builder add(
        String type,
        ImmutableMap.Builder<Path, SourcePath> builder,
        Map<Path, BuildTarget> sourceDescs,
        Map<Path, SourcePath> toAdd,
        BuildTarget sourceDesc) {
      for (Map.Entry<Path, SourcePath> ent : toAdd.entrySet()) {
        add(type, builder, sourceDescs, ent.getKey(), ent.getValue(), sourceDesc);
      }
      return this;
    }

    public Builder addModule(Path destination, SourcePath source, BuildTarget from) {
      return add("module", modules, moduleSources, destination, source, from);
    }

    public Builder addModules(Map<Path, SourcePath> sources, BuildTarget from) {
      return add("module", modules, moduleSources, sources, from);
    }

    public Builder addResources(Map<Path, SourcePath> sources, BuildTarget from) {
      return add("resource", resources, resourceSources, sources, from);
    }

    public Builder addNativeLibraries(Map<Path, SourcePath> sources, BuildTarget from) {
      return add("native library", nativeLibraries, nativeLibrarySources, sources, from);
    }

    public Builder addComponent(PythonPackageComponents other, BuildTarget from) {
      addModules(other.getModules(), from);
      addResources(other.getResources(), from);
      addNativeLibraries(other.getNativeLibraries(), from);
      return this;
    }

    public PythonPackageComponents build() {
      return ImmutablePythonPackageComponents.of(
          modules.build(),
          resources.build(),
          nativeLibraries.build());
    }

  }

}
