// Copyright 2018 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.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.UnmodifiableIterator;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
import java.util.AbstractList;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;

/**
 * A sequence returned by the {@code range} function invocation.
 *
 * <p>Instead of eagerly allocating an array with all elements of the sequence, this class uses
 * simple math to compute a value at each index. This is particularly useful when range is huge or
 * only a few elements from it are used.
 *
 * <p>Eventually {@code range} function should produce an instance of the {@code range} type as is
 * the case in Python 3, but for now to preserve backwards compatibility with Python 2, {@code list}
 * is returned.
 */
@SkylarkModule(
    name = "range",
    category = SkylarkModuleCategory.BUILTIN,
    doc =
        "A language built-in type to support ranges. Example of range literal:<br>"
            + "<pre class=language-python>x = range(1, 10, 3)</pre>"
            + "Accessing elements is possible using indexing (starts from <code>0</code>):<br>"
            + "<pre class=language-python>e = x[1]   # e == 2</pre>"
            + "Ranges do not support the <code>+</code> operator for concatenation."
            + "Similar to strings, ranges support slice operations:"
            + "<pre class=language-python>range(10)[1:3]   # range(1, 3)\n"
            + "range(10)[::2]  # range(0, 10, 2)\n"
            + "range(10)[3:0:-1]  # range(3, 0, -1)</pre>"
            + "Ranges are immutable, as in Python 3.")
final class RangeList extends SkylarkList<Integer> {

  private final int step;
  private final int start;

  private static int computeItem(int start, int step, int index) {
    return start + step * index;
  }

  /** Provides access to range elements based on their index. */
  private static class RangeListView extends AbstractList<Integer> {

    /** Iterator for increasing/decreasing sequences. */
    private static class RangeListIterator extends UnmodifiableIterator<Integer> {
      private final int stop;
      private final int step;

      private int cursor;

      private RangeListIterator(int start, int stop, int step) {
        this.cursor = start;
        this.stop = stop;
        this.step = step;
      }

      @Override
      public boolean hasNext() {
        return (step > 0) ? cursor < stop : cursor > stop;
      }

      @Override
      public Integer next() {
        if (!hasNext()) {
          throw new NoSuchElementException();
        }
        int current = cursor;
        cursor += step;
        return current;
      }
    }

    /**
     * @return The size of the range specified by {@code start}, {@code stop} and {@code step}.
     *     Python version:
     *     https://github.com/python/cpython/blob/09bb918a61031377d720f1a0fa1fe53c962791b6/Objects/rangeobject.c#L144
     */
    private static int computeSize(int start, int stop, int step) {
      // low and high represent bounds of the interval with only one of the sides being open.
      int low;
      int high;
      if (step > 0) {
        low = start;
        high = stop;
      } else {
        low = stop;
        high = start;
        step = -step;
      }
      if (low >= high) {
        return 0;
      }

      int diff = high - low - 1;
      return diff / step + 1;
    }

    private final int start;
    private final int stop;
    private final int step;
    private final int size;

    private RangeListView(int start, int stop, int step) {
      this.start = start;
      this.stop = stop;
      this.step = step;
      this.size = computeSize(start, stop, step);
    }

    @Override
    public Integer get(int index) {
      if (index < 0 || index >= size()) {
        throw new ArrayIndexOutOfBoundsException(index);
      }
      return computeItem(start, step, index);
    }

    @Override
    public int size() {
      return size;
    }

    /**
     * Returns an iterator optimized for traversing range elements, since it's the most frequent
     * operation for which ranges are used.
     */
    @Override
    public Iterator<Integer> iterator() {
      return new RangeListIterator(start, stop, step);
    }

    /** @return the start of the range. */
    public int getStart() {
      return start;
    }

    /** @return the stop element (next after the last one) of the range. */
    public int getStop() {
      return stop;
    }

    /** @return the step between each element of the range. */
    public int getStep() {
      return step;
    }
  }

  private final RangeListView contents;

  private RangeList(int start, int stop, int step) {
    this.step = step;
    this.start = start;
    this.contents = new RangeListView(start, stop, step);
  }

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

  @Override
  public ImmutableList<Integer> getImmutableList() {
    return ImmutableList.copyOf(contents);
  }

  @Override
  public SkylarkList<Integer> getSlice(
      Object start, Object end, Object step, Location loc, Mutability mutability)
      throws EvalException {
    Slice slice = Slice.from(size(), start, end, step, loc);
    int substep = slice.step * this.step;
    int substart = computeItem(this.start, this.step, slice.start);
    int substop = computeItem(this.start, this.step, slice.stop);
    return RangeList.of(substart, substop, substep);
  }

  @Override
  public SkylarkList<Integer> repeat(int times, Mutability mutability) {
    throw new UnsupportedOperationException("Ranges do not support repetition.");
  }

  @Override
  protected List<Integer> getContentsUnsafe() {
    return contents;
  }

  @Override
  public Mutability mutability() {
    return Mutability.IMMUTABLE;
  }

  @Override
  public void repr(SkylarkPrinter printer) {
    if (contents.getStep() == 1) {
      printer.format("range(%d, %d)", contents.getStart(), contents.getStop());
    } else {
      printer.format(
          "range(%d, %d, %d)", contents.getStart(), contents.getStop(), contents.getStep());
    }
  }

  /**
   * @return A half-opened range defined by its starting value (inclusive), stop value (exclusive)
   *     and a step from previous value to the next one.
   */
  static RangeList of(int start, int stop, int step) {
    Preconditions.checkArgument(step != 0);
    return new RangeList(start, stop, step);
  }

  /**
   * Represents a slice produced by applying {@code [start:end:step]} to a {@code range}.
   *
   * <p>{@code start} and {@code stop} define a half-open interval
   *
   * <pre>[start, stop)</pre>
   */
  private static class Slice {

    private final int start;
    private final int stop;
    private final int step;

    private Slice(int start, int stop, int step) {
      this.start = start;
      this.stop = stop;
      this.step = step;
    }

    /**
     * Computes slice indices for the requested range slice.
     *
     * <p>The implementation is based on CPython
     * https://github.com/python/cpython/blob/09bb918a61031377d720f1a0fa1fe53c962791b6/Objects/sliceobject.c#L366-L509
     */
    static Slice from(int length, Object startObj, Object endObj, Object stepObj, Location loc)
        throws EvalException {
      int start;
      int stop;
      int step;

      if (stepObj == Runtime.NONE) {
        step = 1;
      } else if (stepObj instanceof Integer) {
        step = (Integer) stepObj;
      } else {
        throw new EvalException(
            loc, String.format("slice step must be an integer, not '%s'", stepObj));
      }
      if (step == 0) {
        throw new EvalException(loc, "slice step cannot be zero");
      }

      int upper; // upper bound for stop (exclusive)
      int lower; // lower bound for start (inclusive)
      if (step < 0) {
        lower = -1;
        upper = length - 1;
      } else {
        lower = 0;
        upper = length;
      }

      if (startObj == Runtime.NONE) {
        start = step < 0 ? upper : lower;
      } else if (startObj instanceof Integer) {
        start = (Integer) startObj;
        if (start < 0) {
          start += length;
          start = Math.max(start, lower);
        } else {
          start = Math.min(start, upper);
        }
      } else {
        throw new EvalException(
            loc, String.format("slice start must be an integer, not '%s'", startObj));
      }
      if (endObj == Runtime.NONE) {
        stop = step < 0 ? lower : upper;
      } else if (endObj instanceof Integer) {
        stop = (Integer) endObj;
        if (stop < 0) {
          stop += length;
          stop = Math.max(stop, lower);
        } else {
          stop = Math.min(stop, upper);
        }
      } else {
        throw new EvalException(
            loc, String.format("slice end must be an integer, not '%s'", endObj));
      }
      return new Slice(start, stop, step);
    }
  }
}
