# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.

import sys
import os
import re

reHREF = re.compile('<a.*?>(.*?)</a>', re.IGNORECASE)

reMarkup = re.compile('<.*?>')
reDivBlock = re.compile('<div class="block">(.*?)</div>', re.IGNORECASE)
reCaption = re.compile('<caption><span>(.*?)</span>', re.IGNORECASE)
reTDLastNested = re.compile('^<td class="colLast"><code><strong><a href="[^>]*\.([^>]*?)\.html" title="class in[^>]*">', re.IGNORECASE)
reTDLast = re.compile('^<td class="colLast"><code><strong><a href="[^>]*#([^>]*?)">', re.IGNORECASE)
reColOne = re.compile('^<td class="colOne"><code><strong><a href="[^>]*#([^>]*?)">', re.IGNORECASE)

# the Method detail section at the end
reMethodDetail = re.compile('^<h3>Method Detail</h3>$', re.IGNORECASE)
reMethodDetailAnchor = re.compile('^(?:</a>)?<a name="([^>]*?)">$', re.IGNORECASE)
reMethodOverridden = re.compile('^<dt><strong>(Specified by:|Overrides:)</strong></dt>$', re.IGNORECASE)

reTag = re.compile("(?i)<(\/?\w+)((\s+\w+(\s*=\s*(?:\".*?\"|'.*?'|[^'\">\s]+))?)+\s*|\s*)\/?>")

def verifyHTML(s):

  stack = []
  upto = 0
  while True:
    m = reTag.search(s, upto)
    if m is None:
      break
    tag = m.group(1)
    upto = m.end(0)

    if tag[:1] == '/':
      justTag = tag[1:]
    else:
      justTag = tag
      
    if justTag.lower() in ('br', 'li', 'p', 'col'):
      continue

    if tag[:1] == '/':
      if len(stack) == 0:
        raise RuntimeError('saw closing "%s" without opening <%s...>' % (m.group(0), tag[1:]))
      elif stack[-1][0] != tag[1:].lower():
        raise RuntimeError('closing "%s" does not match opening "%s"' % (m.group(0), stack[-1][1]))
      stack.pop()
    else:
      stack.append((tag.lower(), m.group(0)))

  if len(stack) != 0:
    raise RuntimeError('"%s" was never closed' % stack[-1][1])

def cleanHTML(s):
  s = reMarkup.sub('', s)
  s = s.replace('&nbsp;', ' ')
  s = s.replace('&lt;', '<')
  s = s.replace('&gt;', '>')
  s = s.replace('&amp;', '&')
  return s.strip()

reH3 = re.compile('^<h3>(.*?)</h3>', re.IGNORECASE | re.MULTILINE)
reH4 = re.compile('^<h4>(.*?)</h4>', re.IGNORECASE | re.MULTILINE)
  
def checkClassDetails(fullPath):
  """
  Checks for invalid HTML in the full javadocs under each field/method.
  """

  isAttributeSource = fullPath.endswith('AttributeSource.html')

  # TODO: only works with java7 generated javadocs now!
  with open(fullPath, encoding='UTF-8') as f:
    desc = None
    cat = None
    item = None
    errors = []
    for line in f.readlines():

      if isAttributeSource:
        # Work around Javadocs bug that fails to escape the <T> type parameter in {@link #getAttribute} and {@link #addAttribute}
        line = line.replace('<code>getAttribute(java.lang.Class<T>)</code>', '<code>getAttribute(java.lang.Class)</code>')
        line = line.replace('<code>addAttribute(java.lang.Class<T>)</code>', '<code>addAttribute(java.lang.Class)</code>')
      
      m = reH3.search(line)
      if m is not None:
        if desc is not None:
          # Have to fake <ul> context because we pulled a fragment out "across" two <ul>s:
          desc = ''.join(desc)
          if True or cat == 'Constructor Detail':
            idx = desc.find('</div>')
            if idx == -1:
              # Ctor missing javadocs ... checkClassSummaries catches it
              desc = None
              continue
            desc = desc[:idx+6]
          else:
            desc = '<ul>%s</ul>' % ''.join(desc)
          #print('  VERIFY %s: %s: %s' % (cat, item, desc))
          try:
            verifyHTML(desc)
          except RuntimeError as re:
            #print('    FAILED: %s' % re)
            errors.append((cat, item, str(re)))
          desc = None
        cat = m.group(1)
        continue

      m = reH4.search(line)
      if m is not None:
        if desc is not None:
          # Have to fake <ul> context because we pulled a fragment out "across" two <ul>s:
          desc = '<ul>%s</ul>' % ''.join(desc)
          #print('  VERIFY %s: %s: %s' % (cat, item, desc))
          try:
            verifyHTML(desc)
          except RuntimeError as re:
            #print('    FAILED: %s' % re)
            errors.append((cat, item, str(re)))
        item = m.group(1)
        desc = []
        continue

      if desc is not None:
        desc.append(line)

  if len(errors) != 0:
    print()
    print(fullPath)
    for cat, item, message in errors:
      print('  broken details HTML: %s: %s: %s' % (cat, item, message))
    return True
  else:
    return False

def checkClassSummaries(fullPath):

  # TODO: only works with java7 generated javadocs now!
  f = open(fullPath, encoding='UTF-8')

  missing = []
  broken = []
  inThing = False
  lastCaption = None
  lastItem = None

  desc = None

  foundMethodDetail = False
  lastMethodAnchor = None
  
  for line in f.readlines():
    m = reMethodDetail.search(line)
    if m is not None:
      foundMethodDetail = True
      continue

    # prune methods that are just @Overrides of other interface/classes,
    # they should be specified elsewhere, if they are e.g. jdk or 
    # external classes we cannot inherit their docs anyway
    if foundMethodDetail:
      m = reMethodDetailAnchor.search(line)
      if m is not None:
        lastMethodAnchor = m.group(1)
        continue
      m = reMethodOverridden.search(line)
      if m is not None and ('Methods', lastMethodAnchor) in missing:
        #print('removing @overridden method: %s' % lastMethodAnchor)
        missing.remove(('Methods', lastMethodAnchor))

    m = reCaption.search(line)
    if m is not None:
      lastCaption = m.group(1)
      #print('    caption %s' % lastCaption)
    m = reTDLastNested.search(line)
    if m is not None:
      # nested classes
      lastItem = m.group(1)
      #print('      item %s' % lastItem)
    else:
      m = reTDLast.search(line)
      if m is not None:
        # methods etc
        lastItem = m.group(1)
      else:
        # ctors etc
        m = reColOne.search(line)
        if m is not None:
          lastItem = m.group(1)
          #print('      item %s' % lastItem)

    lineLower = line.strip().lower()

    if lineLower.find('<tr class="') != -1:
      inThing = True
      hasDesc = False
      continue

    if inThing:
      if lineLower.find('</tr>') != -1:
        if not hasDesc:
          missing.append((lastCaption, lastItem))
        inThing = False
        continue
      else:
        if line.find('<div class="block">') != -1:
          desc = []
        if desc is not None:
          desc.append(line)
          if line.find('</div>') != -1:
            desc = ''.join(desc)

            try:
              verifyHTML(desc)
            except RuntimeError as e:
              broken.append((lastCaption, lastItem, str(e)))
              #print('FAIL: %s: %s: %s: %s' % (lastCaption, lastItem, e, desc))
                            
            desc = desc.replace('<div class="block">', '')
            desc = desc.replace('</div>', '')
            desc = desc.strip()
            hasDesc = len(desc) > 0

            desc = None
  f.close()
  if len(missing) > 0 or len(broken) > 0:
    print()
    print(fullPath)
    for (caption, item) in missing:
      print('  missing %s: %s' % (caption, item))
    for (caption, item, why) in broken:
      print('  broken HTML: %s: %s: %s' % (caption, item, why))
    return True
  else:
    return False
  
def checkSummary(fullPath):
  printed = False
  f = open(fullPath, encoding='UTF-8')
  anyMissing = False
  sawPackage = False
  desc = []
  lastHREF = None
  for line in f.readlines():
    lineLower = line.strip().lower()
    if desc is not None:
      # TODO: also detect missing description in overview-summary
      if lineLower.startswith('package ') or lineLower.startswith('<h1 title="package" '):
        sawPackage = True
      elif sawPackage:
        if lineLower.startswith('<table ') or lineLower.startswith('<b>see: '):
          desc = ' '.join(desc)
          desc = reMarkup.sub(' ', desc)
          desc = desc.strip()
          if desc == '':
            if not printed:
              print()
              print(fullPath)
              printed = True
            print('  no package description (missing package.html in src?)')
            anyMissing = True
          desc = None
        else:
          desc.append(lineLower)
      
    if lineLower in ('<td>&nbsp;</td>', '<td></td>', '<td class="collast">&nbsp;</td>'):
      if not printed:
        print()
        print(fullPath)
        printed = True
      print('  missing: %s' % unescapeHTML(lastHREF))
      anyMissing = True
    elif lineLower.find('licensed to the apache software foundation') != -1 or lineLower.find('copyright 2004 the apache software foundation') != -1:
      if not printed:
        print()
        print(fullPath)
        printed = True
      print('  license-is-javadoc: %s' % unescapeHTML(lastHREF))
      anyMissing = True
    m = reHREF.search(line)
    if m is not None:
      lastHREF = m.group(1)
  if desc is not None and fullPath.find('/overview-summary.html') == -1:
    raise RuntimeError('BUG: failed to locate description in %s' % fullPath)
  f.close()
  return anyMissing

def unescapeHTML(s):
  s = s.replace('&lt;', '<')
  s = s.replace('&gt;', '>')
  s = s.replace('&amp;', '&')
  return s

def checkPackageSummaries(root, level='class'):
  """
  Just checks for blank summary lines in package-summary.html; returns
  True if there are problems.
  """

  if level != 'class' and level != 'package' and level != 'method' and level != 'none':
    print('unsupported level: %s, must be "class" or "package" or "method" or "none"' % level)
    sys.exit(1)
  
  #for dirPath, dirNames, fileNames in os.walk('%s/lucene/build/docs/api' % root):

  if False:
    os.chdir(root)
    print()
    print('Run "ant javadocs" > javadocs.log...')
    if os.system('ant javadocs > javadocs.log 2>&1'):
      print('  FAILED')
      sys.exit(1)
    
  anyMissing = False
  if not os.path.isdir(root):
    checkClassSummaries(root)
    checkClassDetails(root)
    sys.exit(0)
    
  for dirPath, dirNames, fileNames in os.walk(root):

    if dirPath.find('/all/') != -1:
      # These are dups (this is a bit risk, eg, root IS this /all/ directory..)
      continue

    if 'package-summary.html' in fileNames:
      if (level == 'class' or level == 'method') and checkSummary('%s/package-summary.html' % dirPath):
        anyMissing = True
      for fileName in fileNames:
        fullPath = '%s/%s' % (dirPath, fileName)
        if not fileName.startswith('package-') and fileName.endswith('.html') and os.path.isfile(fullPath):
          if level == 'method':
            if checkClassSummaries(fullPath):
              anyMissing = True
          # always look for broken html, regardless of level supplied
          if checkClassDetails(fullPath):
            anyMissing = True
              
    if 'overview-summary.html' in fileNames:        
      if level != 'none' and checkSummary('%s/overview-summary.html' % dirPath):
        anyMissing = True

  return anyMissing

if __name__ == '__main__':
  if len(sys.argv) < 2 or len(sys.argv) > 3:
    print('usage: %s <dir> [none|package|class|method]' % sys.argv[0])
    sys.exit(1)
  if len(sys.argv) == 2:
    level = 'class'
  else:
    level = sys.argv[2]
  if checkPackageSummaries(sys.argv[1], level):
    print()
    print('Missing javadocs were found!')
    sys.exit(1)
  sys.exit(0)
