// 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.syntax;

import com.google.common.annotations.VisibleForTesting;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.cmdline.LabelValidator;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.Objects;

/**
 * Factory class for creating appropriate instances of {@link SkylarkImports}.
 */
public class SkylarkImports {

  private SkylarkImports() {
    throw new IllegalStateException("This class should not be instantiated");
  }

  // Default implementation class for SkylarkImport.
  private abstract static class SkylarkImportImpl implements SkylarkImport {
    private final String importString;

    protected SkylarkImportImpl(String importString) {
      this.importString = importString;
    }

    @Override
    public String getImportString() {
      return importString;
    }

    @Override
    public abstract PathFragment asPathFragment();

    @Override
    public abstract Label getLabel(Label containingFileLabel);

    @Override
    public boolean hasAbsolutePath() {
      return false;
    }

    @Override
    public PathFragment getAbsolutePath() {
      throw new IllegalStateException("can't request absolute path from a non-absolute import");
    }

    @Override
    public int hashCode() {
      return Objects.hash(getClass(), importString);
    }

    @Override
    public boolean equals(Object that) {
      if (this == that) {
        return true;
      }

      if (!(that instanceof SkylarkImportImpl)) {
        return false;
      }

      return Objects.equals(getClass(), that.getClass())
          && Objects.equals(importString, ((SkylarkImportImpl) that).importString);
    }
  }

  private static final class AbsolutePathImport extends SkylarkImportImpl {
    private final PathFragment importPath;

    private AbsolutePathImport(String importString, PathFragment importPath) {
      super(importString);
      this.importPath = importPath;
    }

    @Override
    public PathFragment asPathFragment() {
      return importPath;
    }

    @Override
    public Label getLabel(Label containingFileLabel) {
      throw new IllegalStateException("can't request a label from an absolute path import");
    }

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

    @Override
    public PathFragment getAbsolutePath() {
      return this.importPath;
    }

  }

  private static final class RelativePathImport extends SkylarkImportImpl {
    private final String importFile;

    private RelativePathImport(String importString, String importFile) {
      super(importString);
      this.importFile = importFile;
    }

    @Override
    public PathFragment asPathFragment() {
      return PathFragment.create(importFile);
    }

    @Override
    public Label getLabel(Label containingFileLabel) {
      // The twistiness of the code below is due to the fact that the containing file may be in
      // a subdirectory of the package that contains it. We need to construct a Label with
      // the imported file in the same subdirectory of the package.
      PathFragment containingDirInPkg =
          PathFragment.create(containingFileLabel.getName()).getParentDirectory();
      String targetNameForImport = containingDirInPkg.getRelative(importFile).toString();
      try {
        return containingFileLabel.getRelative(targetNameForImport);
      } catch (LabelSyntaxException e) {
        // Shouldn't happen because the parent label is assumed to be valid and the target string is
        // validated on construction.
        throw new IllegalStateException(e);
      }
    }

  }

  private static final class AbsoluteLabelImport extends SkylarkImportImpl {
    private final Label importLabel;

    private AbsoluteLabelImport(String importString, Label importLabel) {
      super(importString);
      this.importLabel = importLabel;
    }

    @Override
    public PathFragment asPathFragment() {
      return PathFragment.create(PathFragment.ROOT_DIR).getRelative(importLabel.toPathFragment());
    }

    @Override
    public Label getLabel(Label containingFileLabel) {
      // When the import label contains no explicit repository identifier, we resolve it relative
      // to the repo of the containing file.
      return containingFileLabel.resolveRepositoryRelative(importLabel);
    }

  }

  private static final class RelativeLabelImport extends SkylarkImportImpl {
    private final String importTarget;

    private RelativeLabelImport(String importString, String importTarget) {
      super(importString);
      this.importTarget = importTarget;
    }

    @Override
    public PathFragment asPathFragment() {
      return PathFragment.create(importTarget);
    }

    @Override
    public Label getLabel(Label containingFileLabel) {
      // Unlike a relative path import, the import target is relative to the containing package,
      // not the containing directory within the package.
      try {
        return containingFileLabel.getRelative(importTarget);
      } catch (LabelSyntaxException e) {
        // shouldn't happen because the parent label is assumed validated and the target string is
        // validated on construction
        throw new IllegalStateException(e);
      }
    }

  }

  /**
   * Exception raised for syntactically-invalid Skylark load strings.
   */
  public static class SkylarkImportSyntaxException extends Exception {
    public SkylarkImportSyntaxException(String message) {
      super(message);
    }
  }

  @VisibleForTesting
  static final String INVALID_LABEL_PREFIX = "Invalid label: ";

  @VisibleForTesting
  static final String MUST_HAVE_BZL_EXT_MSG =
      "The label must reference a file with extension '.bzl'";

  @VisibleForTesting
  static final String EXTERNAL_PKG_NOT_ALLOWED_MSG =
      "Skylark files may not be loaded from the //external package";

  @VisibleForTesting
  static final String INVALID_PATH_SYNTAX =
      "Don't use paths for Load statements; "
      + "use a label instead, e.g. '//foo:bar.bzl' or ':bar.bzl'";

  @VisibleForTesting
  static final String INVALID_TARGET_PREFIX = "Invalid target: ";

  @VisibleForTesting
  static final String INVALID_FILENAME_PREFIX = "Invalid filename: ";

  /**
   * Creates and syntactically validates a {@link SkylarkImports} instance from a string.
   * <p>
   * There four syntactic import variants: Absolute paths, relative paths, absolute labels, and
   * relative labels
   *
   * @throws SkylarkImportSyntaxException if the string is not a valid Skylark import.
   */
  public static SkylarkImport create(String importString) throws SkylarkImportSyntaxException {
    if (importString.startsWith("//") || importString.startsWith("@")) {
      // Absolute label.
      Label importLabel;
      try {
        importLabel = Label.parseAbsolute(importString, false);
      } catch (LabelSyntaxException e) {
        throw new SkylarkImportSyntaxException(INVALID_LABEL_PREFIX + e.getMessage());
      }
      String targetName = importLabel.getName();
      if (!targetName.endsWith(".bzl")) {
        throw new SkylarkImportSyntaxException(MUST_HAVE_BZL_EXT_MSG);
      }
      PackageIdentifier packageId = importLabel.getPackageIdentifier();
      if (packageId.equals(Label.EXTERNAL_PACKAGE_IDENTIFIER)) {
        throw new SkylarkImportSyntaxException(EXTERNAL_PKG_NOT_ALLOWED_MSG);
      }
      return new AbsoluteLabelImport(importString, importLabel);
    } else if (importString.startsWith("/")) {
      // Absolute path.
      if (importString.endsWith(".bzl")) {
        throw new SkylarkImportSyntaxException(INVALID_PATH_SYNTAX);
      }
      PathFragment importPath = PathFragment.create(importString + ".bzl");
      return new AbsolutePathImport(importString, importPath);
    } else if (importString.startsWith(":")) {
      // Relative label. We require that relative labels use an explicit ':' prefix to distinguish
      // them from relative paths, which have a different semantics.
      String importTarget = importString.substring(1);
      if (!importTarget.endsWith(".bzl")) {
        throw new SkylarkImportSyntaxException(MUST_HAVE_BZL_EXT_MSG);
      }
      String maybeErrMsg = LabelValidator.validateTargetName(importTarget);
      if (maybeErrMsg != null) {
        // Null indicates successful target validation.
        throw new SkylarkImportSyntaxException(INVALID_TARGET_PREFIX + maybeErrMsg);
      }
      return new RelativeLabelImport(importString, importTarget);
    } else {
      // Relative path.
      if (importString.endsWith(".bzl") || importString.contains("/")) {
        throw new SkylarkImportSyntaxException(INVALID_PATH_SYNTAX);
      }
      String importTarget = importString + ".bzl";
      String maybeErrMsg = LabelValidator.validateTargetName(importTarget);
      if (maybeErrMsg != null) {
        // Null indicates successful target validation.
        throw new SkylarkImportSyntaxException(INVALID_FILENAME_PREFIX + maybeErrMsg);
      }
      return new RelativePathImport(importString, importTarget);
    }
  }
}
