#!/usr/bin/python
#

# Copyright (C) 2011, 2012, 2013 Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


"""Script to check NEWS file.

"""

# pylint: disable=C0103
# [C0103] Invalid name

import sys
import time
import datetime
import locale
import fileinput
import re
import os


DASHES_RE = re.compile(r"^\s*-+\s*$")
RELEASED_RE = re.compile(r"^\*\(Released (?P<day>[A-Z][a-z]{2}),"
                         r" (?P<date>.+)\)\*$")
UNRELEASED_RE = re.compile(r"^\*\(unreleased\)\*$")
VERSION_RE = re.compile(r"^Version (\d+(\.\d+)+( (alpha|beta|rc)\d+)?)$")

#: How many days release timestamps may be in the future
TIMESTAMP_FUTURE_DAYS_MAX = 5

errors = []


def Error(msg):
  """Log an error for later display.

  """
  errors.append(msg)


def ReqNLines(req, count_empty, lineno, line):
  """Check if we have N empty lines before the current one.

  """
  if count_empty < req:
    Error("Line %s: Missing empty line(s) before %s,"
          " %d needed but got only %d" %
          (lineno, line, req, count_empty))
  if count_empty > req:
    Error("Line %s: Too many empty lines before %s,"
          " %d needed but got %d" %
          (lineno, line, req, count_empty))


def IsAlphaVersion(version):
  return "alpha" in version


def UpdateAllowUnreleased(allow_unreleased, version_match, release):
  if not allow_unreleased:
    return False
  if IsAlphaVersion(release):
    return True
  version = version_match.group(1)
  if version == release:
    return False
  return True


def main():
  # Ensure "C" locale is used
  curlocale = locale.getlocale()
  if curlocale != (None, None):
    Error("Invalid locale %s" % curlocale)

  # Get the release version, but replace "~" with " " as the version
  # in the NEWS file uses spaces for beta and rc releases.
  release = os.environ.get('RELEASE', "").replace("~", " ")

  prevline = None
  expect_date = False
  count_empty = 0
  allow_unreleased = True
  found_versions = set()

  for line in fileinput.input():
    line = line.rstrip("\n")

    version_match = VERSION_RE.match(line)
    if version_match:
      ReqNLines(2, count_empty, fileinput.filelineno(), line)
      version = version_match.group(1)
      if version in found_versions:
        Error("Line %s: Duplicate release %s found" %
              (fileinput.filelineno(), version))
      found_versions.add(version)
      allow_unreleased = UpdateAllowUnreleased(allow_unreleased, version_match,
                                               release)

    unreleased_match = UNRELEASED_RE.match(line)
    if unreleased_match and not allow_unreleased:
      Error("Line %s: Unreleased version after current release %s" %
            (fileinput.filelineno(), release))

    if unreleased_match or RELEASED_RE.match(line):
      ReqNLines(1, count_empty, fileinput.filelineno(), line)

    if line:
      count_empty = 0
    else:
      count_empty += 1

    if DASHES_RE.match(line):
      if not VERSION_RE.match(prevline):
        Error("Line %s: Invalid title" %
              (fileinput.filelineno() - 1))
      if len(line) != len(prevline):
        Error("Line %s: Invalid dashes length" %
              (fileinput.filelineno()))
      expect_date = True

    elif expect_date:
      if not line:
        # Ignore empty lines
        continue

      if UNRELEASED_RE.match(line):
        # Ignore unreleased versions
        expect_date = False
        continue

      m = RELEASED_RE.match(line)
      if not m:
        Error("Line %s: Invalid release line" % fileinput.filelineno())
        expect_date = False
        continue

      # Including the weekday in the date string does not work as time.strptime
      # would return an inconsistent result if the weekday is incorrect.
      parsed_ts = time.mktime(time.strptime(m.group("date"), "%d %b %Y"))
      parsed = datetime.date.fromtimestamp(parsed_ts)
      today = datetime.date.today()

      if (parsed - datetime.timedelta(TIMESTAMP_FUTURE_DAYS_MAX)) > today:
        Error("Line %s: %s is more than %s days in the future (today is %s)" %
              (fileinput.filelineno(), parsed, TIMESTAMP_FUTURE_DAYS_MAX,
               today))

      weekday = parsed.strftime("%a")

      # Check weekday
      if m.group("day") != weekday:
        Error("Line %s: %s was/is a %s, not %s" %
              (fileinput.filelineno(), parsed, weekday,
               m.group("day")))

      expect_date = False

    prevline = line

  if errors:
    for msg in errors:
      print >> sys.stderr, msg
    sys.exit(1)
  else:
    sys.exit(0)


if __name__ == "__main__":
  main()
