// Copyright 2014 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.events;

import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.io.Serializable;
import java.util.Objects;

/**
 * A Location is a range of characters within a file.
 *
 * <p>The start and end locations may be the same, in which case the Location denotes a point in the
 * file, not a range. The path may be null, indicating an unknown file.
 *
 * <p>Implementations of Location should be optimised for speed of construction, not speed of
 * attribute access, as far more Locations are created during parsing than are ever used to display
 * error messages.
 */
public abstract class Location implements Serializable {
  @AutoCodec
  @Immutable
  static final class LocationWithPathAndStartColumn extends Location {
    private final PathFragment path;
    private final LineAndColumn startLineAndColumn;

    LocationWithPathAndStartColumn(
        PathFragment path, int startOffset, int endOffset, LineAndColumn startLineAndColumn) {
      super(startOffset, endOffset);
      this.path = path;
      this.startLineAndColumn = startLineAndColumn;
    }

    @Override
    public PathFragment getPath() { return path; }

    @Override
    public LineAndColumn getStartLineAndColumn() {
      return startLineAndColumn;
    }

    @Override
    public int hashCode() {
      return Objects.hash(path, startLineAndColumn, internalHashCode());
    }

    @Override
    public boolean equals(Object other) {
      if (other == null || !other.getClass().equals(getClass())) {
        return false;
      }
      LocationWithPathAndStartColumn that = (LocationWithPathAndStartColumn) other;
      return internalEquals(that)
          && Objects.equals(this.path, that.path)
          && Objects.equals(this.startLineAndColumn, that.startLineAndColumn);
    }
  }

  protected final int startOffset;
  protected final int endOffset;

  /**
   * Returns a Location with a given Path, start and end offset and start line and column info. 
   */
  public static Location fromPathAndStartColumn(PathFragment path,  int startOffSet, int endOffSet,
      LineAndColumn startLineAndColumn) {
    return new LocationWithPathAndStartColumn(path, startOffSet, endOffSet, startLineAndColumn);
  }

  /**
   * Returns a Location relating to file 'path', but not to any specific part
   * region within the file.  Try to use a more specific location if possible.
   */
  public static Location fromFile(Path path) {
    return fromFileAndOffsets(path.asFragment(), 0, 0);
  }

  public static Location fromPathFragment(PathFragment path) {
    return fromFileAndOffsets(path, 0, 0);
  }
  /**
   * Returns a Location relating to the subset of file 'path', starting at
   * 'startOffset' and ending at 'endOffset'.
   */
  public static Location fromFileAndOffsets(final PathFragment path,
                                            int startOffset,
                                            int endOffset) {
    return new LocationWithPathAndStartColumn(path, startOffset, endOffset, null);
  }

  protected Location(int startOffset, int endOffset) {
    this.startOffset = startOffset;
    this.endOffset = endOffset;
  }

  /**
   * Returns the start offset relative to the beginning of the file the object
   * resides in.
   */
  public final int getStartOffset() {
    return startOffset;
  }

  /**
   * Returns the end offset relative to the beginning of the file the object resides in.
   *
   * <p>The end offset is one position past the last character in range, making this method behave
   * in a compatible fashion with {@link String#substring(int, int)}. (By contrast, {@link
   * #getEndLineAndColumn} returns the actual end position.)
   *
   * <p>To compute the length of this location, use {@code getEndOffset() - getStartOffset()}.
   */
  public final int getEndOffset() {
    return endOffset;
  }

  /**
   * Returns the path of the file to which the start/end offsets refer.  May be
   * null if the file name information is not available.
   *
   * <p>This method is intentionally abstract, as a space optimisation.  Some
   * subclass instances implement sharing of common data (e.g. tables for
   * converting offsets into line numbers) and this enables them to share the
   * Path value in the same way.
   */
  public abstract PathFragment getPath();

  /**
   * Returns a (line, column) pair corresponding to the position denoted by
   * getStartOffset.  Returns null if this information is not available.
   */
  public LineAndColumn getStartLineAndColumn() {
    return null;
  }

  /**
   * Returns a line corresponding to the position denoted by getStartOffset.
   * Returns null if this information is not available.
   */
  public Integer getStartLine() {
    LineAndColumn lac = getStartLineAndColumn();
    if (lac == null) {
      return null;
    }
    return lac.getLine();
  }

  /**
   * Returns a (line, column) pair corresponding to the end position or null if this information is
   * unavailable.
   *
   * <p>The returned line and column are the position of the last character in the location range.
   * (By contrast, {@link #getEndOffset} returns the position <strong>past</strong> the actual end
   * position.) In particular, this means that the location spans {@code
   * getEndLineAndColumn().getColumn() - getStartLineAndColumn().getColumn() + 1} columns but
   * contains {@code getEndOffset() - getStartOffset()} characters.
   */
  public LineAndColumn getEndLineAndColumn() {
    return null;
  }

  /**
   * A default implementation of toString() that formats the location in the
   * following ways based on the amount of information available:
   * <pre>
   *    "foo.cc:23:2"
   *    "23:2"
   *    "foo.cc:char offsets 123--456"
   *    "char offsets 123--456"
   * </pre>
   */
  public String print() {
    return printWithPath(getPath());
  }

  private String printWithPath(PathFragment path) {
    StringBuilder buf = new StringBuilder();
    if (path != null) {
      buf.append(path).append(':');
    }
    LineAndColumn start = getStartLineAndColumn();
    if (start == null) {
      if (getStartOffset() == 0 && getEndOffset() == 0) {
        buf.append("1"); // i.e. line 1 (special case: no information at all)
      } else {
        buf.append("char offsets ").
            append(getStartOffset()).append("--").append(getEndOffset());
      }
    } else {
      buf.append(start.getLine()).append(':').append(start.getColumn());
    }
    return buf.toString();
  }

  /**
   * A default implementation of toString() that formats the location in the following ways based on
   * the amount of information available:
   *
   * <pre>
   *   "foo.cc:23:2"
   *   "23:2"
   *   "foo.cc:char offsets 123--456"
   *   "char offsets 123--456"
   * </pre>
   *
   * <p>This version replace the package's path with the relative package path. I.e., if {@code
   * packagePath} is equivalent to "/absolute/path/to/workspace/pack/age" and {@code
   * relativePackage} is equivalent to "pack/age" then the result for the 2nd character of the 23rd
   * line of the "foo/bar.cc" file in "pack/age" would be "pack/age/foo/bar.cc:23:2" whereas with
   * {@link #print()} the result would be "/absolute/path/to/workspace/pack/age/foo/bar.cc:23:2".
   *
   * <p>If {@code packagePath} is not a parent of the location path, then the result of this
   * function is the same as the result of {@link #print()}.
   */
  public String print(PathFragment packagePath, PathFragment relativePackage) {
    PathFragment path = getPath();
    if (path == null) {
      return printWithPath(null);
    } else if (path.startsWith(packagePath)) {
      return printWithPath(relativePackage.getRelative(path.relativeTo(packagePath)));
    } else {
      return printWithPath(path);
    }
  }

  /**
   * Prints the object in a sort of reasonable way. This should never be used in user-visible
   * places, only for debugging and testing.
   */
  @Override
  public String toString() {
    return print();
  }

  protected int internalHashCode() {
    return Objects.hash(startOffset, endOffset);
  }

  protected boolean internalEquals(Location that) {
    return this.startOffset == that.startOffset && this.endOffset == that.endOffset;
  }

  /** A value class that describes the line and column of an offset in a file. */
  @AutoCodec
  @Immutable
  public static final class LineAndColumn {
    private final int line;
    private final int column;

    public LineAndColumn(int line, int column) {
      this.line = line;
      this.column = column;
    }

    public int getLine() {
      return line;
    }

    public int getColumn() {
      return column;
    }

    @Override
    public boolean equals(Object o) {
      if (o == this) {
        return true;
      }
      if (!(o instanceof LineAndColumn)) {
        return false;
      }
      LineAndColumn lac = (LineAndColumn) o;
      return lac.line == line && lac.column == column;
    }

    @Override
    public int hashCode() {
      return line * 41 + column;
    }
  }

  static final class BuiltinLocation extends Location {
    private BuiltinLocation() {
      super(0, 0);
    }

    @Override
    public String toString() {
      return "Built-In";
    }

    @Override
    public PathFragment getPath() {
      return null;
    }

    @Override
    public int hashCode() {
      return internalHashCode();
    }

    @Override
    public boolean equals(Object object) {
      return object instanceof BuiltinLocation;
    }
  }

  /**
   * Dummy location for built-in functions which ensures that stack traces contain "nice" location
   * strings.
   */
  @AutoCodec public static final Location BUILTIN = new BuiltinLocation();

  /**
   * Returns the location in the format "filename:line".
   *
   * <p>If such a location is not defined, this method returns an empty string.
   */
  public static String printLocation(Location location) {
    if (location == null) {
      return "";
    }

    StringBuilder builder = new StringBuilder();
    PathFragment path = location.getPath();
    if (path != null) {
      builder.append(path.getPathString());
    }

    LineAndColumn position = location.getStartLineAndColumn();
    if (position != null) {
      builder.append(":").append(position.getLine());
    }
    return builder.toString();
  }
}
