// Copyright 2011 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_DATEPARSER_H_
#define V8_DATEPARSER_H_

#include "src/allocation.h"
#include "src/char-predicates.h"
#include "src/parsing/scanner.h"

namespace v8 {
namespace internal {

class DateParser : public AllStatic {
 public:
  // Parse the string as a date. If parsing succeeds, return true after
  // filling out the output array as follows (all integers are Smis):
  // [0]: year
  // [1]: month (0 = Jan, 1 = Feb, ...)
  // [2]: day
  // [3]: hour
  // [4]: minute
  // [5]: second
  // [6]: millisecond
  // [7]: UTC offset in seconds, or null value if no timezone specified
  // If parsing fails, return false (content of output array is not defined).
  template <typename Char>
  static bool Parse(Isolate* isolate, Vector<Char> str, FixedArray* output);

  enum {
    YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, MILLISECOND, UTC_OFFSET, OUTPUT_SIZE
  };

 private:
  // Range testing
  static inline bool Between(int x, int lo, int hi) {
    return static_cast<unsigned>(x - lo) <= static_cast<unsigned>(hi - lo);
  }

  // Indicates a missing value.
  static const int kNone = kMaxInt;

  // Maximal number of digits used to build the value of a numeral.
  // Remaining digits are ignored.
  static const int kMaxSignificantDigits = 9;

  // InputReader provides basic string parsing and character classification.
  template <typename Char>
  class InputReader BASE_EMBEDDED {
   public:
    InputReader(UnicodeCache* unicode_cache, Vector<Char> s)
        : index_(0),
          buffer_(s),
          unicode_cache_(unicode_cache) {
      Next();
    }

    int position() { return index_; }

    // Advance to the next character of the string.
    void Next() {
      ch_ = (index_ < buffer_.length()) ? buffer_[index_] : 0;
      index_++;
    }

    // Read a string of digits as an unsigned number. Cap value at
    // kMaxSignificantDigits, but skip remaining digits if the numeral
    // is longer.
    int ReadUnsignedNumeral() {
      int n = 0;
      int i = 0;
      while (IsAsciiDigit()) {
        if (i < kMaxSignificantDigits) n = n * 10 + ch_ - '0';
        i++;
        Next();
      }
      return n;
    }

    // Read a word (sequence of chars. >= 'A'), fill the given buffer with a
    // lower-case prefix, and pad any remainder of the buffer with zeroes.
    // Return word length.
    int ReadWord(uint32_t* prefix, int prefix_size) {
      int len;
      for (len = 0; IsAsciiAlphaOrAbove(); Next(), len++) {
        if (len < prefix_size) prefix[len] = AsciiAlphaToLower(ch_);
      }
      for (int i = len; i < prefix_size; i++) prefix[i] = 0;
      return len;
    }

    // The skip methods return whether they actually skipped something.
    bool Skip(uint32_t c) {
      if (ch_ == c) {
        Next();
        return true;
      }
      return false;
    }

    inline bool SkipWhiteSpace();
    inline bool SkipParentheses();

    // Character testing/classification. Non-ASCII digits are not supported.
    bool Is(uint32_t c) const { return ch_ == c; }
    bool IsEnd() const { return ch_ == 0; }
    bool IsAsciiDigit() const { return IsDecimalDigit(ch_); }
    bool IsAsciiAlphaOrAbove() const { return ch_ >= 'A'; }
    bool IsAsciiSign() const { return ch_ == '+' || ch_ == '-'; }

    // Return 1 for '+' and -1 for '-'.
    int GetAsciiSignValue() const { return 44 - static_cast<int>(ch_); }

   private:
    int index_;
    Vector<Char> buffer_;
    uint32_t ch_;
    UnicodeCache* unicode_cache_;
  };

  enum KeywordType {
      INVALID, MONTH_NAME, TIME_ZONE_NAME, TIME_SEPARATOR, AM_PM
  };

  struct DateToken {
   public:
    bool IsInvalid() { return tag_ == kInvalidTokenTag; }
    bool IsUnknown() { return tag_ == kUnknownTokenTag; }
    bool IsNumber() { return tag_ == kNumberTag; }
    bool IsSymbol() { return tag_ == kSymbolTag; }
    bool IsWhiteSpace() { return tag_ == kWhiteSpaceTag; }
    bool IsEndOfInput() { return tag_ == kEndOfInputTag; }
    bool IsKeyword() { return tag_ >= kKeywordTagStart; }

    int length() { return length_; }

    int number() {
      DCHECK(IsNumber());
      return value_;
    }
    KeywordType keyword_type() {
      DCHECK(IsKeyword());
      return static_cast<KeywordType>(tag_);
    }
    int keyword_value() {
      DCHECK(IsKeyword());
      return value_;
    }
    char symbol() {
      DCHECK(IsSymbol());
      return static_cast<char>(value_);
    }
    bool IsSymbol(char symbol) {
      return IsSymbol() && this->symbol() == symbol;
    }
    bool IsKeywordType(KeywordType tag) {
      return tag_ == tag;
    }
    bool IsFixedLengthNumber(int length) {
      return IsNumber() && length_ == length;
    }
    bool IsAsciiSign() {
      return tag_ == kSymbolTag && (value_ == '-' || value_ == '+');
    }
    int ascii_sign() {
      DCHECK(IsAsciiSign());
      return 44 - value_;
    }
    bool IsKeywordZ() {
      return IsKeywordType(TIME_ZONE_NAME) && length_ == 1 && value_ == 0;
    }
    bool IsUnknown(int character) {
      return IsUnknown() && value_ == character;
    }
    // Factory functions.
    static DateToken Keyword(KeywordType tag, int value, int length) {
      return DateToken(tag, length, value);
    }
    static DateToken Number(int value, int length) {
      return DateToken(kNumberTag, length, value);
    }
    static DateToken Symbol(char symbol) {
      return DateToken(kSymbolTag, 1, symbol);
    }
    static DateToken EndOfInput() {
      return DateToken(kEndOfInputTag, 0, -1);
    }
    static DateToken WhiteSpace(int length) {
      return DateToken(kWhiteSpaceTag, length, -1);
    }
    static DateToken Unknown() {
      return DateToken(kUnknownTokenTag, 1, -1);
    }
    static DateToken Invalid() {
      return DateToken(kInvalidTokenTag, 0, -1);
    }

   private:
    enum TagType {
      kInvalidTokenTag = -6,
      kUnknownTokenTag = -5,
      kWhiteSpaceTag = -4,
      kNumberTag = -3,
      kSymbolTag = -2,
      kEndOfInputTag = -1,
      kKeywordTagStart = 0
    };
    DateToken(int tag, int length, int value)
        : tag_(tag),
          length_(length),
          value_(value) { }

    int tag_;
    int length_;  // Number of characters.
    int value_;
  };

  template <typename Char>
  class DateStringTokenizer {
   public:
    explicit DateStringTokenizer(InputReader<Char>* in)
        : in_(in), next_(Scan()) { }
    DateToken Next() {
      DateToken result = next_;
      next_ = Scan();
      return result;
    }

    DateToken Peek() {
      return next_;
    }
    bool SkipSymbol(char symbol) {
      if (next_.IsSymbol(symbol)) {
        next_ = Scan();
        return true;
      }
      return false;
    }

   private:
    DateToken Scan();

    InputReader<Char>* in_;
    DateToken next_;
  };

  static int ReadMilliseconds(DateToken number);

  // KeywordTable maps names of months, time zones, am/pm to numbers.
  class KeywordTable : public AllStatic {
   public:
    // Look up a word in the keyword table and return an index.
    // 'pre' contains a prefix of the word, zero-padded to size kPrefixLength
    // and 'len' is the word length.
    static int Lookup(const uint32_t* pre, int len);
    // Get the type of the keyword at index i.
    static KeywordType GetType(int i) {
      return static_cast<KeywordType>(array[i][kTypeOffset]);
    }
    // Get the value of the keyword at index i.
    static int GetValue(int i) { return array[i][kValueOffset]; }

    static const int kPrefixLength = 3;
    static const int kTypeOffset = kPrefixLength;
    static const int kValueOffset = kTypeOffset + 1;
    static const int kEntrySize = kValueOffset + 1;
    static const int8_t array[][kEntrySize];
  };

  class TimeZoneComposer BASE_EMBEDDED {
   public:
    TimeZoneComposer() : sign_(kNone), hour_(kNone), minute_(kNone) {}
    void Set(int offset_in_hours) {
      sign_ = offset_in_hours < 0 ? -1 : 1;
      hour_ = offset_in_hours * sign_;
      minute_ = 0;
    }
    void SetSign(int sign) { sign_ = sign < 0 ? -1 : 1; }
    void SetAbsoluteHour(int hour) { hour_ = hour; }
    void SetAbsoluteMinute(int minute) { minute_ = minute; }
    bool IsExpecting(int n) const {
      return hour_ != kNone && minute_ == kNone && TimeComposer::IsMinute(n);
    }
    bool IsUTC() const { return hour_ == 0 && minute_ == 0; }
    bool Write(FixedArray* output);
    bool IsEmpty() { return hour_ == kNone; }
   private:
    int sign_;
    int hour_;
    int minute_;
  };

  class TimeComposer BASE_EMBEDDED {
   public:
    TimeComposer() : index_(0), hour_offset_(kNone) {}
    bool IsEmpty() const { return index_ == 0; }
    bool IsExpecting(int n) const {
      return (index_ == 1 && IsMinute(n)) ||
             (index_ == 2 && IsSecond(n)) ||
             (index_ == 3 && IsMillisecond(n));
    }
    bool Add(int n) {
      return index_ < kSize ? (comp_[index_++] = n, true) : false;
    }
    bool AddFinal(int n) {
      if (!Add(n)) return false;
      while (index_ < kSize) comp_[index_++] = 0;
      return true;
    }
    void SetHourOffset(int n) { hour_offset_ = n; }
    bool Write(FixedArray* output);

    static bool IsMinute(int x) { return Between(x, 0, 59); }
    static bool IsHour(int x) { return Between(x, 0, 23); }
    static bool IsSecond(int x) { return Between(x, 0, 59); }

   private:
    static bool IsHour12(int x) { return Between(x, 0, 12); }
    static bool IsMillisecond(int x) { return Between(x, 0, 999); }

    static const int kSize = 4;
    int comp_[kSize];
    int index_;
    int hour_offset_;
  };

  class DayComposer BASE_EMBEDDED {
   public:
    DayComposer() : index_(0), named_month_(kNone), is_iso_date_(false) {}
    bool IsEmpty() const { return index_ == 0; }
    bool Add(int n) {
      if (index_ < kSize) {
        comp_[index_] = n;
        index_++;
        return true;
      }
      return false;
    }
    void SetNamedMonth(int n) { named_month_ = n; }
    bool Write(FixedArray* output);
    void set_iso_date() { is_iso_date_ = true; }
    static bool IsMonth(int x) { return Between(x, 1, 12); }
    static bool IsDay(int x) { return Between(x, 1, 31); }

   private:
    static const int kSize = 3;
    int comp_[kSize];
    int index_;
    int named_month_;
    // If set, ensures that data is always parsed in year-month-date order.
    bool is_iso_date_;
  };

  // Tries to parse an ES5 Date Time String. Returns the next token
  // to continue with in the legacy date string parser. If parsing is
  // complete, returns DateToken::EndOfInput(). If terminally unsuccessful,
  // returns DateToken::Invalid(). Otherwise parsing continues in the
  // legacy parser.
  template <typename Char>
  static DateParser::DateToken ParseES5DateTime(
      DateStringTokenizer<Char>* scanner, DayComposer* day, TimeComposer* time,
      TimeZoneComposer* tz);
};


}  // namespace internal
}  // namespace v8

#endif  // V8_DATEPARSER_H_
