// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "google_apis/drive/time_util.h"

#include <string>
#include <vector>

#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"

namespace google_apis {
namespace util {

namespace {

const char kNullTimeString[] = "null";

bool ParseTimezone(const base::StringPiece& timezone,
                   bool ahead,
                   int* out_offset_to_utc_in_minutes) {
  DCHECK(out_offset_to_utc_in_minutes);

  std::vector<base::StringPiece> parts = base::SplitStringPiece(
      timezone, ":", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);

  int hour = 0;
  if (parts.empty() || !base::StringToInt(parts[0], &hour))
    return false;

  int minute = 0;
  if (parts.size() > 1 && !base::StringToInt(parts[1], &minute))
    return false;

  *out_offset_to_utc_in_minutes = (hour * 60 + minute) * (ahead ? +1 : -1);
  return true;
}

}  // namespace

bool GetTimeFromString(const base::StringPiece& raw_value,
                       base::Time* parsed_time) {
  base::StringPiece date;
  base::StringPiece time_and_tz;
  base::StringPiece time;
  base::Time::Exploded exploded = {0};
  bool has_timezone = false;
  int offset_to_utc_in_minutes = 0;

  // Splits the string into "date" part and "time" part.
  {
    std::vector<base::StringPiece> parts = base::SplitStringPiece(
        raw_value, "T", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
    if (parts.size() != 2)
      return false;
    date = parts[0];
    time_and_tz = parts[1];
  }

  // Parses timezone suffix on the time part if available.
  {
    std::vector<base::StringPiece> parts;
    if (time_and_tz.back() == 'Z') {
      // Timezone is 'Z' (UTC)
      has_timezone = true;
      offset_to_utc_in_minutes = 0;
      time = time_and_tz;
      time.remove_suffix(1);
    } else {
      parts = base::SplitStringPiece(
          time_and_tz, "+", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
      if (parts.size() == 2) {
        // Timezone is "+hh:mm" format
        if (!ParseTimezone(parts[1], true, &offset_to_utc_in_minutes))
          return false;
        has_timezone = true;
        time = parts[0];
      } else {
        parts = base::SplitStringPiece(
            time_and_tz, "-", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
        if (parts.size() == 2) {
          // Timezone is "-hh:mm" format
          if (!ParseTimezone(parts[1], false, &offset_to_utc_in_minutes))
            return false;
          has_timezone = true;
          time = parts[0];
        } else {
          // No timezone (uses local timezone)
          time = time_and_tz;
        }
      }
    }
  }

  // Parses the date part.
  {
    std::vector<base::StringPiece> parts = base::SplitStringPiece(
        date, "-", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
    if (parts.size() != 3)
      return false;

    if (!base::StringToInt(parts[0], &exploded.year) ||
        !base::StringToInt(parts[1], &exploded.month) ||
        !base::StringToInt(parts[2], &exploded.day_of_month)) {
      return false;
    }
  }

  // Parses the time part.
  {
    std::vector<base::StringPiece> parts = base::SplitStringPiece(
        time, ":", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
    if (parts.size() != 3)
      return false;

    if (!base::StringToInt(parts[0], &exploded.hour) ||
        !base::StringToInt(parts[1], &exploded.minute)) {
      return false;
    }

    std::vector<base::StringPiece> seconds_parts = base::SplitStringPiece(
        parts[2], ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
    if (seconds_parts.size() >= 3)
      return false;

    if (!base::StringToInt(seconds_parts[0], &exploded.second))
      return false;

    // Only accept milli-seconds (3-digits).
    if (seconds_parts.size() > 1 &&
        seconds_parts[1].length() == 3 &&
        !base::StringToInt(seconds_parts[1], &exploded.millisecond)) {
      return false;
    }
  }

  exploded.day_of_week = 0;
  if (!exploded.HasValidValues())
    return false;

  if (has_timezone) {
    if (!base::Time::FromUTCExploded(exploded, parsed_time))
      return false;
    if (offset_to_utc_in_minutes != 0)
      *parsed_time -= base::TimeDelta::FromMinutes(offset_to_utc_in_minutes);
  } else {
    if (!base::Time::FromLocalExploded(exploded, parsed_time))
      return false;
  }

  return true;
}

std::string FormatTimeAsString(const base::Time& time) {
  if (time.is_null())
    return kNullTimeString;

  base::Time::Exploded exploded;
  time.UTCExplode(&exploded);
  return base::StringPrintf(
      "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ",
      exploded.year, exploded.month, exploded.day_of_month,
      exploded.hour, exploded.minute, exploded.second, exploded.millisecond);
}

std::string FormatTimeAsStringLocaltime(const base::Time& time) {
  if (time.is_null())
    return kNullTimeString;

  base::Time::Exploded exploded;
  time.LocalExplode(&exploded);
  return base::StringPrintf(
      "%04d-%02d-%02dT%02d:%02d:%02d.%03d",
      exploded.year, exploded.month, exploded.day_of_month,
      exploded.hour, exploded.minute, exploded.second, exploded.millisecond);
}

}  // namespace util
}  // namespace google_apis
