#! /usr/bin/env python3
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('Usage: make_drs [<path to cwg_index.html>]', file=sys.stderr)
  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, open(test_cpp, 'r').read()):
    status_map[int(match.group(1))] = match.group(2)
    found_any = True
  if not found_any:
    print("warning:%s: no '// dr123: foo' comments in this file" % test_cpp, file=sys.stderr)

drs = sorted((parse(dr) for dr in open(index, 'r').read().split('<TR>')[2:]),
             key = lambda dr: dr.issue)
out_file = open(output, 'w')
out_file.write('''\
<!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("issue %s marked as sup %s" % (issue, dup), file=sys.stderr)
        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

  out_file.write('''
  <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))

out_file.write('''\
</table>

</div>
</body>
</html>
''')
out_file.close()

