#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2012 Google Inc.
#
# Licensed 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.

"""Build wiki page with a list of all samples.

The information for the wiki page is built from data found in all the README
files in the samples. The format of the README file is:


   Description is everything up to the first blank line.

   api: plus  (Used to look up the long name in discovery).
   keywords: appengine (such as appengine, oauth2, cmdline)

   The rest of the file is ignored when it comes to building the index.
"""

import httplib2
import itertools
import json
import os
import re

BASE_HG_URI = ('http://code.google.com/p/google-api-python-client/source/'
               'browse/#hg')

http = httplib2.Http('.cache')
r, c =  http.request('https://www.googleapis.com/discovery/v1/apis')
if r.status != 200:
  raise ValueError('Received non-200 response when retrieving Discovery.')

# Dictionary mapping api names to their discovery description.
DIRECTORY = {}
for item in json.loads(c)['items']:
  if item['preferred']:
    DIRECTORY[item['name']] = item

# A list of valid keywords. Should not be taken as complete, add to
# this list as needed.
KEYWORDS = {
    'appengine': 'Google App Engine',
    'oauth2': 'OAuth 2.0',
    'cmdline': 'Command-line',
    'django': 'Django',
    'threading': 'Threading',
    'pagination': 'Pagination',
    'media': 'Media Upload and Download'
    }


def get_lines(name, lines):
  """Return lines that begin with name.

  Lines are expected to look like:

     name: space separated values

  Args:
    name: string, parameter name.
    lines: iterable of string, lines in the file.

  Returns:
    List of values in the lines that match.
  """
  retval = []
  matches = itertools.ifilter(lambda x: x.startswith(name + ':'), lines)
  for line in matches:
    retval.extend(line[len(name)+1:].split())
  return retval


def wiki_escape(s):
  """Detect WikiSyntax (i.e. InterCaps, a.k.a. CamelCase) and escape it."""
  ret = []
  for word in s.split():
    if re.match(r'[A-Z]+[a-z]+[A-Z]', word):
      word = '!%s' % word
    ret.append(word)
  return ' '.join(ret)


def context_from_sample(api, keywords, dirname, desc, uri):
  """Return info for expanding a sample into a template.

  Args:
    api: string, name of api.
    keywords: list of string, list of keywords for the given api.
    dirname: string, directory name of the sample.
    desc: string, long description of the sample.
    uri: string, uri of the sample code if provided in the README.

  Returns:
    A dictionary of values useful for template expansion.
  """
  if uri is None:
    uri = BASE_HG_URI + dirname.replace('/', '%2F')
  else:
    uri = ''.join(uri)
  if api is None:
    return None
  else:
    entry = DIRECTORY[api]
    context = {
        'api': api,
        'version': entry['version'],
        'api_name': wiki_escape(entry.get('title', entry.get('description'))),
        'api_desc': wiki_escape(entry['description']),
        'api_icon': entry['icons']['x32'],
        'keywords': keywords,
        'dir': dirname,
        'uri': uri,
        'desc': wiki_escape(desc),
        }
    return context


def keyword_context_from_sample(keywords, dirname, desc, uri):
  """Return info for expanding a sample into a template.

  Sample may not be about a specific api.

  Args:
    keywords: list of string, list of keywords for the given api.
    dirname: string, directory name of the sample.
    desc: string, long description of the sample.
    uri: string, uri of the sample code if provided in the README.

  Returns:
    A dictionary of values useful for template expansion.
  """
  if uri is None:
    uri = BASE_HG_URI + dirname.replace('/', '%2F')
  else:
    uri = ''.join(uri)
  context = {
      'keywords': keywords,
      'dir': dirname,
      'uri': uri,
      'desc': wiki_escape(desc),
      }
  return context


def scan_readme_files(dirname):
  """Scans all subdirs of dirname for README files.

  Args:
    dirname: string, name of directory to walk.

  Returns:
    (samples, keyword_set): list of information about all samples, the union
      of all keywords found.
  """
  samples = []
  keyword_set = set()

  for root, dirs, files in os.walk(dirname):
    if 'README' in files:
      filename = os.path.join(root, 'README')
      with open(filename, 'r') as f:
        content = f.read()
        lines = content.splitlines()
        desc = ' '.join(itertools.takewhile(lambda x: x, lines))
        api = get_lines('api', lines)
        keywords = get_lines('keywords', lines)
        uri = get_lines('uri', lines)
        if not uri:
          uri = None

        for k in keywords:
          if k not in KEYWORDS:
            raise ValueError(
                '%s is not a valid keyword in file %s' % (k, filename))
        keyword_set.update(keywords)
        if not api:
          api = [None]
        samples.append((api[0], keywords, root[1:], desc, uri))

  samples.sort()

  return samples, keyword_set


def main():
  # Get all the information we need out of the README files in the samples.
  samples, keyword_set = scan_readme_files('./samples')

  # Now build a wiki page with all that information. Accumulate all the
  # information as string to be concatenated when were done.
  page = ['<wiki:toc max_depth="3" />\n= Samples By API =\n']

  # All the samples, grouped by API.
  current_api = None
  for api, keywords, dirname, desc, uri in samples:
    context = context_from_sample(api, keywords, dirname, desc, uri)
    if context is None:
      continue
    if current_api != api:
      page.append("""
=== %(api_icon)s %(api_name)s ===

%(api_desc)s

Documentation for the %(api_name)s in [https://google-api-client-libraries.appspot.com/documentation/%(api)s/%(version)s/python/latest/ PyDoc]

""" % context)
      current_api = api

    page.append('|| [%(uri)s %(dir)s] || %(desc)s ||\n' % context)

  # Now group the samples by keywords.
  for keyword, keyword_name in KEYWORDS.iteritems():
    if keyword not in keyword_set:
      continue
    page.append('\n= %s Samples =\n\n' % keyword_name)
    page.append('<table border=1 cellspacing=0 cellpadding=8px>\n')
    for _, keywords, dirname, desc, uri in samples:
      context = keyword_context_from_sample(keywords, dirname, desc, uri)
      if keyword not in keywords:
        continue
      page.append("""
<tr>
  <td>[%(uri)s %(dir)s] </td>
  <td> %(desc)s </td>
</tr>""" % context)
    page.append('</table>\n')

  print ''.join(page)


if __name__ == '__main__':
  main()
