// Copyright 2016 Google Inc. 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.

#include "time_zone_posix.h"

#include <cstddef>
#include <cstring>
#include <limits>
#include <string>

namespace absl {
namespace time_internal {
namespace cctz {

namespace {

const char kDigits[] = "0123456789";

const char* ParseInt(const char* p, int min, int max, int* vp) {
  int value = 0;
  const char* op = p;
  const int kMaxInt = std::numeric_limits<int>::max();
  for (; const char* dp = strchr(kDigits, *p); ++p) {
    int d = static_cast<int>(dp - kDigits);
    if (d >= 10) break;  // '\0'
    if (value > kMaxInt / 10) return nullptr;
    value *= 10;
    if (value > kMaxInt - d) return nullptr;
    value += d;
  }
  if (p == op || value < min || value > max) return nullptr;
  *vp = value;
  return p;
}

// abbr = <.*?> | [^-+,\d]{3,}
const char* ParseAbbr(const char* p, std::string* abbr) {
  const char* op = p;
  if (*p == '<') {  // special zoneinfo <...> form
    while (*++p != '>') {
      if (*p == '\0') return nullptr;
    }
    abbr->assign(op + 1, static_cast<std::size_t>(p - op) - 1);
    return ++p;
  }
  while (*p != '\0') {
    if (strchr("-+,", *p)) break;
    if (strchr(kDigits, *p)) break;
    ++p;
  }
  if (p - op < 3) return nullptr;
  abbr->assign(op, static_cast<std::size_t>(p - op));
  return p;
}

// offset = [+|-]hh[:mm[:ss]] (aggregated into single seconds value)
const char* ParseOffset(const char* p, int min_hour, int max_hour, int sign,
                        std::int_fast32_t* offset) {
  if (p == nullptr) return nullptr;
  if (*p == '+' || *p == '-') {
    if (*p++ == '-') sign = -sign;
  }
  int hours = 0;
  int minutes = 0;
  int seconds = 0;

  p = ParseInt(p, min_hour, max_hour, &hours);
  if (p == nullptr) return nullptr;
  if (*p == ':') {
    p = ParseInt(p + 1, 0, 59, &minutes);
    if (p == nullptr) return nullptr;
    if (*p == ':') {
      p = ParseInt(p + 1, 0, 59, &seconds);
      if (p == nullptr) return nullptr;
    }
  }
  *offset = sign * ((((hours * 60) + minutes) * 60) + seconds);
  return p;
}

// datetime = ( Jn | n | Mm.w.d ) [ / offset ]
const char* ParseDateTime(const char* p, PosixTransition* res) {
  if (p != nullptr && *p == ',') {
    if (*++p == 'M') {
      int month = 0;
      if ((p = ParseInt(p + 1, 1, 12, &month)) != nullptr && *p == '.') {
        int week = 0;
        if ((p = ParseInt(p + 1, 1, 5, &week)) != nullptr && *p == '.') {
          int weekday = 0;
          if ((p = ParseInt(p + 1, 0, 6, &weekday)) != nullptr) {
            res->date.fmt = PosixTransition::M;
            res->date.m.month = static_cast<int_fast8_t>(month);
            res->date.m.week = static_cast<int_fast8_t>(week);
            res->date.m.weekday = static_cast<int_fast8_t>(weekday);
          }
        }
      }
    } else if (*p == 'J') {
      int day = 0;
      if ((p = ParseInt(p + 1, 1, 365, &day)) != nullptr) {
        res->date.fmt = PosixTransition::J;
        res->date.j.day = static_cast<int_fast16_t>(day);
      }
    } else {
      int day = 0;
      if ((p = ParseInt(p, 0, 365, &day)) != nullptr) {
        res->date.fmt = PosixTransition::N;
        res->date.j.day = static_cast<int_fast16_t>(day);
      }
    }
  }
  if (p != nullptr) {
    res->time.offset = 2 * 60 * 60;  // default offset is 02:00:00
    if (*p == '/') p = ParseOffset(p + 1, -167, 167, 1, &res->time.offset);
  }
  return p;
}

}  // namespace

// spec = std offset [ dst [ offset ] , datetime , datetime ]
bool ParsePosixSpec(const std::string& spec, PosixTimeZone* res) {
  const char* p = spec.c_str();
  if (*p == ':') return false;

  p = ParseAbbr(p, &res->std_abbr);
  p = ParseOffset(p, 0, 24, -1, &res->std_offset);
  if (p == nullptr) return false;
  if (*p == '\0') return true;

  p = ParseAbbr(p, &res->dst_abbr);
  if (p == nullptr) return false;
  res->dst_offset = res->std_offset + (60 * 60);  // default
  if (*p != ',') p = ParseOffset(p, 0, 24, -1, &res->dst_offset);

  p = ParseDateTime(p, &res->dst_start);
  p = ParseDateTime(p, &res->dst_end);

  return p != nullptr && *p == '\0';
}

}  // namespace cctz
}  // namespace time_internal
}  // namespace absl
