#! /usr/bin/env python
import sys, os, re

index = 'cwg_index.html'
output = 'cxx_dr_status.html'
dr_test_dir = '../test/CXX/drs'

if len(sys.argv) == 1:
  pass
elif len(sys.argv) == 2:
  index = sys.argv[1]
else:
  print >>sys.stderr, 'Usage: make_drs [<path to cwg_index.html>]'
  sys.exit(1)

class DR:
  def __init__(self, section, issue, url, status, title):
    self.section, self.issue, self.url, self.status, self.title = \
        section, issue, url, status, title
  def __repr__(self):
    return '%s (%s): %s' % (self.issue, self.status, self.title)

def parse(dr):
  section, issue_link, status, title = [
      col.split('>', 1)[1].split('</TD>')[0]
      for col in dr.split('</TR>', 1)[0].split('<TD')[1:]
  ]
  _, url, issue = issue_link.split('"', 2)
  url = url.strip()
  issue = int(issue.split('>', 1)[1].split('<', 1)[0])
  title = title.replace('<issue_title>', '').replace('</issue_title>', '').replace('\r\n', '\n').strip()
  return DR(section, issue, url, status, title)

status_re = re.compile(r'\bdr([0-9]+): (.*)')
status_map = {}
for test_cpp in os.listdir(dr_test_dir):
  if not test_cpp.endswith('.cpp'):
    continue
  test_cpp = os.path.join(dr_test_dir, test_cpp)
  found_any = False;
  for match in re.finditer(status_re, file(test_cpp, 'r').read()):
    status_map[int(match.group(1))] = match.group(2)
    found_any = True
  if not found_any:
    print >> sys.stderr, "warning:%s: no '// dr123: foo' comments in this file" % test_cpp

drs = sorted((parse(dr) for dr in file(index, 'r').read().split('<TR>')[2:]),
             key = lambda dr: dr.issue)
out_file = file(output, 'w')

print >> out_file, '''\
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
          "http://www.w3.org/TR/html4/strict.dtd">
<!-- This file is auto-generated by make_cxx_dr_status. Do not modify. -->
<html>
<head>
  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
  <title>Clang - C++ Defect Report Status</title>
  <link type="text/css" rel="stylesheet" href="menu.css">
  <link type="text/css" rel="stylesheet" href="content.css">
  <style type="text/css">
    .none { background-color: #FFCCCC }
    .partial { background-color: #FFE0B0 }
    .unreleased { background-color: #FFFF99 }
    .full { background-color: #CCFF99 }
    .na { background-color: #DDDDDD }
    .open * { color: #AAAAAA }
    //.open { filter: opacity(0.2) }
    tr:target { background-color: #FFFFBB }
    th { background-color: #FFDDAA }
  </style>
</head>
<body>

<!--#include virtual="menu.html.incl"-->

<div id="content">

<!--*************************************************************************-->
<h1>C++ Defect Report Support in Clang</h1>
<!--*************************************************************************-->

<h2 id="cxxdr">C++ defect report implementation status</h2>

<p>This page tracks which C++ defect reports are implemented within Clang.</p>

<table width="689" border="1" cellspacing="0">
  <tr>
    <th>Number</th>
    <th>Status</th>
    <th>Issue title</th>
    <th>Available in Clang?</th>
  </tr>'''

latest_release = 13

def availability(issue):
  status = status_map.get(issue, 'unknown')
  avail_suffix = ''
  if status.endswith(' c++11'):
    status = status[:-6]
    avail_suffix = ' (C++11 onwards)'
  elif status.endswith(' c++14'):
    status = status[:-6]
    avail_suffix = ' (C++14 onwards)'
  elif status.endswith(' c++17'):
    status = status[:-6]
    avail_suffix = ' (C++17 onwards)'
  if status == 'unknown':
    avail = 'Unknown'
    avail_style = ' class="none"'
  elif re.match('^[0-9]+\.?[0-9]*', status):
    avail = 'Clang %s' % status
    if float(status) > latest_release:
      avail_style = ' class="unreleased"'
    else:
      avail_style = ' class="full"'
  elif status == 'yes':
    avail = 'Yes'
    avail_style = ' class="full"'
  elif status == 'partial':
    avail = 'Partial'
    avail_style = ' class="partial"'
  elif status == 'no':
    avail = 'No'
    avail_style = ' class="none"'
  elif status == 'na':
    avail = 'N/A'
    avail_style = ' class="na"'
  elif status == 'na lib':
    avail = 'N/A (Library DR)'
    avail_style = ' class="na"'
  elif status == 'na abi':
    avail = 'N/A (ABI constraint)'
    avail_style = ' class="na"'
  elif status.startswith('sup '):
    dup = status.split(' ', 1)[1]
    if dup.startswith('P'):
      avail = 'Superseded by <a href="https://wg21.link/%s">%s</a>' % (dup, dup)
      avail_style = ' class="na"'
    else:
      avail = 'Superseded by <a href="#%s">%s</a>' % (dup, dup)
      try:
        _, avail_style = availability(int(dup))
      except:
        print >>sys.stderr, "issue %s marked as sup %s" % (issue, dup)
        avail_style = ' class="none"'
  elif status.startswith('dup '):
    dup = int(status.split(' ', 1)[1])
    avail = 'Duplicate of <a href="#%s">%s</a>' % (dup, dup)
    _, avail_style = availability(dup)
  else:
    assert False, 'unknown status %s for issue %s' % (status, dr.issue)
  return (avail + avail_suffix, avail_style)

count = {}
for dr in drs:
  if dr.status in ('concepts',):
    # This refers to the old ("C++0x") concepts feature, which was not part
    # of any C++ International Standard or Technical Specification.
    continue
  if dr.status in ('open', 'concurrency', 'drafting', 'review', 'extension'):
    # We may have to deal with these some day, but not yet.
    row_style = ' class="open"'
    if dr.status == 'extension':
      avail = 'Extension'
    else:
      avail = 'Not resolved'
    avail_style = ''
    assert dr.issue not in status_map, "have status for not-ready dr %s" % dr.issue
  else:
    row_style = ''
    avail, avail_style = availability(dr.issue)
    if not avail.startswith('Sup') and not avail.startswith('Dup'):
      count[avail] = count.get(avail, 0) + 1

  print >> out_file, '''\
  <tr%s id="%s">
    <td><a href="https://wg21.link/cwg%s">%s</a></td>
    <td>%s</td>
    <td>%s</td>
    <td%s align="center">%s</td>
  </tr>''' % (row_style, dr.issue, dr.issue, dr.issue, dr.status, dr.title, avail_style, avail)

for status, num in sorted(count.items()):
  print "%s: %s" % (status, num)

print >> out_file, '''\
</table>

</div>
</body>
</html>'''
