/*
 * 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.AbstractBuildRuleBuilder;
import com.facebook.buck.rules.AbstractCachingBuildRule;
import com.facebook.buck.rules.AbstractDependencyVisitor;
import com.facebook.buck.rules.BinaryBuildRule;
import com.facebook.buck.rules.BuildContext;
import com.facebook.buck.rules.BuildRule;
import com.facebook.buck.rules.BuildRuleParams;
import com.facebook.buck.rules.BuildRuleType;
import com.facebook.buck.rules.RuleKey;
import com.facebook.buck.step.Step;
import com.facebook.buck.util.Functions;
import com.google.common.base.Joiner;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;

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

public class PythonBinaryRule extends AbstractCachingBuildRule implements BinaryBuildRule {

  private final String main;

  protected PythonBinaryRule(BuildRuleParams buildRuleParams, String main) {
    super(buildRuleParams);
    this.main = Preconditions.checkNotNull(main);
  }

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

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

  @Override
  public String getExecutableCommand() {
    String pythonPath = Joiner.on(':').join(Iterables.transform(getPythonPathEntries(),
        Functions.RELATIVE_TO_ABSOLUTE_PATH));
    return String.format("PYTHONPATH=%s python %s",
        pythonPath,
        Functions.RELATIVE_TO_ABSOLUTE_PATH.apply(main));
  }

  private ImmutableSet<String> getPythonPathEntries() {
    final ImmutableSet.Builder<String> entries = ImmutableSet.builder();

    final PythonBinaryRule pythonBinaryRule = this;
    new AbstractDependencyVisitor(this) {

      @Override
      public boolean visit(BuildRule rule) {
        if (rule instanceof PythonLibraryRule) {
          PythonLibraryRule pythonLibraryRule = (PythonLibraryRule)rule;

          Optional<String> pythonPathEntry = pythonLibraryRule.getPythonPathDirectory();
          if (pythonPathEntry.isPresent()) {
            entries.add(pythonPathEntry.get());
          }
          return true;
        }

        // AbstractDependencyVisitor will start from this (PythonBinaryRule) so make sure it
        // descends to its dependencies even though it is not a library rule.
        return rule == pythonBinaryRule;
      }

    }.start();

    return entries.build();
  }

  @Override
  protected Iterable<String> getInputsToCompareToOutput(BuildContext context) {
    if (main != null) {
      return ImmutableList.of(main);
    } else {
      return ImmutableList.of();
    }
  }

  @Override
  protected List<Step> buildInternal(BuildContext context)
      throws IOException {
    // TODO(mbolin): Package Python code, if appropriate. There does not appear to be a standard
    // cross-platform way to do this.
    return ImmutableList.of();
  }

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

  public static class Builder extends AbstractBuildRuleBuilder {

    private String main;

    private Builder() {}

    @Override
    public PythonBinaryRule build(Map<String, BuildRule> buildRuleIndex) {
      return new PythonBinaryRule(createBuildRuleParams(buildRuleIndex), main);
    }

    public Builder setMain(String main) {
      this.main = main;
      return this;
    }
  }
}
