/*
 * Copyright 2012-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.rules.AbstractCachingBuildRule;
import com.facebook.buck.rules.AbstractCachingBuildRuleBuilder;
import com.facebook.buck.rules.BuildContext;
import com.facebook.buck.rules.BuildRule;
import com.facebook.buck.rules.BuildRuleType;
import com.facebook.buck.rules.CachingBuildRuleParams;
import com.facebook.buck.rules.RuleKey;
import com.facebook.buck.rules.SrcsAttributeBuilder;
import com.facebook.buck.step.fs.MakeCleanDirectoryStep;
import com.facebook.buck.step.fs.SymlinkFileStep;
import com.facebook.buck.step.Step;
import com.facebook.buck.util.BuckConstant;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSortedSet;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;

public class PythonLibraryRule extends AbstractCachingBuildRule {

  private final ImmutableSortedSet<String> srcs;
  private final Optional<String> pythonPathDirectory;

  protected PythonLibraryRule(CachingBuildRuleParams cachingBuildRuleParams,
      ImmutableSortedSet<String> srcs) {
    super(cachingBuildRuleParams);
    this.srcs = Preconditions.checkNotNull(srcs);

    if (srcs.isEmpty()) {
      this.pythonPathDirectory = Optional.absent();
    } else {
      this.pythonPathDirectory = Optional.of(getPathToPythonPathDirectory());
    }
  }

  @Override
  public boolean isLibrary() {
    return true;
  }

  @Override
  protected RuleKey.Builder ruleKeyBuilder() {
    return super.ruleKeyBuilder()
        .set("srcs", srcs)
        .set("pythonPathDirectory", pythonPathDirectory);
  }

  private String getPathToPythonPathDirectory() {
    return String.format("%s/%s/__pylib_%s/",
        BuckConstant.BIN_DIR,
        getBuildTarget().getBasePath(),
        getBuildTarget().getShortName());
  }

  public ImmutableSortedSet<String> getPythonSrcs() {
    return srcs;
  }

  @Override
  protected Iterable<String> getInputsToCompareToOutput(BuildContext context) {
    return srcs;
  }

  public Optional<String> getPythonPathDirectory() {
    return pythonPathDirectory;
  }

  @Override
  protected List<Step> buildInternal(BuildContext context) throws IOException {
    ImmutableList.Builder<Step> commands = ImmutableList.builder();

    // Symlink all of the sources to a generated directory so that the generated directory can be
    // included as a $PYTHONPATH element.
    // TODO(mbolin): Do not flatten the directory structure when creating the symlinks, as directory
    // structure is significant in Python when __init__.py is used.
    if (!srcs.isEmpty()) {
      commands.add(new MakeCleanDirectoryStep(getPathToPythonPathDirectory()));
      File pythonPathDirectory = new File(getPathToPythonPathDirectory());
      for (String src : srcs) {
        File source = new File(src);
        File target = new File(pythonPathDirectory, new File(src).getName());
        commands.add(new SymlinkFileStep(source, target));
      }
    }

    return commands.build();
  }

  @Override
  public BuildRuleType getType() {
    return BuildRuleType.PYTHON_LIBRARY;
  }

  public static Builder newPythonLibraryBuilder() {
    return new Builder();
  }

  public static class Builder extends AbstractCachingBuildRuleBuilder
      implements SrcsAttributeBuilder {
    protected ImmutableSortedSet.Builder<String> srcs = ImmutableSortedSet.naturalOrder();

    private Builder() {}

    @Override
    public AbstractCachingBuildRuleBuilder addSrc(String src) {
      srcs.add(src);
      return this;
    }

    @Override
    public PythonLibraryRule build(Map<String, BuildRule> buildRuleIndex) {
      CachingBuildRuleParams cachingBuildRuleParams = createCachingBuildRuleParams(buildRuleIndex);
      return new PythonLibraryRule(cachingBuildRuleParams, srcs.build());
    }
  }
}
