// 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 {
inline namespace lts_2018_06_20 {
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
}  // inline namespace lts_2018_06_20
}  // namespace absl
