#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2014 Google Inc. All Rights Reserved.
#
# 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()
