/*
 * 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.java;

import com.facebook.buck.io.MorePaths;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.rules.BuildTargetSourcePath;
import com.facebook.buck.rules.SourcePath;
import com.facebook.buck.rules.SourcePathResolver;
import com.facebook.buck.step.ExecutionContext;
import com.facebook.buck.step.Step;
import com.facebook.buck.step.fs.MkdirAndSymlinkFileStep;
import com.facebook.buck.util.BuckConstant;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CopyResourcesStep implements Step {

  /**
   * This matches the Path for a BuildTargetSourcePath and returns the path without the
   * "buck-out/XXX/" component as the first capturing group.
   */
  private static final Pattern GENERATED_FILE_PATTERN = Pattern.compile(
      "^(?:" +
          Joiner.on('|').join(
              BuckConstant.ANNOTATION_DIR,
              BuckConstant.BIN_DIR,
              BuckConstant.GEN_DIR
          ) + ")/(.*)");

  private final SourcePathResolver resolver;
  private final BuildTarget target;
  private final Collection<? extends SourcePath> resources;
  private final Path outputDirectory;
  private final JavaPackageFinder javaPackageFinder;

  public CopyResourcesStep(
      SourcePathResolver resolver,
      BuildTarget target,
      Collection<? extends SourcePath> resources,
      Path outputDirectory,
      JavaPackageFinder javaPackageFinder) {
    this.resolver = resolver;
    this.target = target;
    this.resources = resources;
    this.outputDirectory = outputDirectory;
    this.javaPackageFinder = javaPackageFinder;
  }

  @Override
  public int execute(ExecutionContext context) throws IOException, InterruptedException {
    for (Step step : buildSteps()) {
      int result = step.execute(context);
      if (result != 0) {
        return result;
      }
    }
    return 0;
  }

  @VisibleForTesting
  ImmutableList<Step> buildSteps() {
    ImmutableList.Builder<Step> allSteps = ImmutableList.builder();

    if (resources.isEmpty()) {
      return allSteps.build();
    }

    String targetPackageDir = javaPackageFinder.findJavaPackageForPath(
        target.getBasePathWithSlash())
        .replace('.', File.separatorChar);

    for (SourcePath rawResource : resources) {
      // If the path to the file defining this rule were:
      // "first-party/orca/lib-http/tests/com/facebook/orca/BUCK"
      //
      // And the value of resource were:
      // "first-party/orca/lib-http/tests/com/facebook/orca/protocol/base/batch_exception1.txt"
      //
      // Assuming that `src_roots = tests` were in the [java] section of the .buckconfig file,
      // then javaPackageAsPath would be:
      // "com/facebook/orca/protocol/base/"
      //
      // And the path that we would want to copy to the classes directory would be:
      // "com/facebook/orca/protocol/base/batch_exception1.txt"
      //
      // Therefore, some path-wrangling is required to produce the correct string.

      final Path pathToResource = resolver.getPath(rawResource);
      String resource = MorePaths.pathWithUnixSeparators(pathToResource);
      Matcher matcher;
      if ((matcher = GENERATED_FILE_PATTERN.matcher(resource)).matches()) {
        resource = matcher.group(1);
      }
      String javaPackageAsPath = javaPackageFinder.findJavaPackageFolderForPath(resource);

      Path relativeSymlinkPath;
      if ("".equals(javaPackageAsPath)) {
        // In this case, the project root is acting as the default package, so the resource path
        // works fine.
        relativeSymlinkPath = pathToResource.getFileName();
      } else {
        int lastIndex = resource.lastIndexOf(javaPackageAsPath);
        if (lastIndex < 0) {
          Preconditions.checkState(
              rawResource instanceof BuildTargetSourcePath,
              "If resource path %s does not contain %s, then it must be a BuildTargetSourcePath.",
              pathToResource,
              javaPackageAsPath);
          // Handle the case where we depend on the output of another BuildRule. In that case, just
          // grab the output and put in the same package as this target would be in.
          relativeSymlinkPath = Paths.get(
              String.format(
                  "%s%s%s",
                  targetPackageDir,
                  targetPackageDir.isEmpty() ? "" : "/",
                  resolver.getPath(rawResource).getFileName()));
        } else {
          relativeSymlinkPath = Paths.get(resource.substring(lastIndex));
        }
      }
      Path target = outputDirectory.resolve(relativeSymlinkPath);
      MkdirAndSymlinkFileStep link = new MkdirAndSymlinkFileStep(pathToResource, target);
      allSteps.add(link);
    }
    return allSteps.build();
  }

  @Override
  public String getShortName() {
    return "copy_resources";
  }

  @Override
  public String getDescription(ExecutionContext context) {
    return String.format("%s of %s", getShortName(), target);
  }
}
