// 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());
  }

  public 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();
  }
}
