#!/usr/bin/env python
#
# Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

# Run this script to generate documentation for a directory and serve
# the results to localhost for viewing in the browser.

import optparse
import os
from os.path import join, dirname, abspath, exists
import platform
import subprocess
import sys
sys.path.append(abspath(join(dirname(__file__), '../../../tools')))
import utils

DIRECTORY = abspath(dirname(__file__))
DART_DIR = dirname(dirname(dirname(DIRECTORY)))
DART_EXECUTABLE = join(DART_DIR,
    '%s/%s/dart-sdk/bin/dart' % (utils.BUILD_ROOT[utils.GuessOS()],
    utils.GetBuildConf('release', utils.GuessArchitecture())))
PUB = join(DART_DIR, 'sdk/bin/pub')
DART2JS = join(DART_DIR, 'sdk/bin/dart2js')
PACKAGE_ROOT = join(dirname(dirname(dirname(DART_EXECUTABLE[:-(len('dart'))]))),
    'packages/')
EXCLUDED_PACKAGES = ['browser', 'html_import', 'mutation_observer',
    'pkg.xcodeproj', 'shadow_dom']
APPSERVER_EXECUTABLE = 'dev_appserver.py'


def SetPackageRoot(path):
  global PACKAGE_ROOT
  if exists(path):
    PACKAGE_ROOT = abspath(path)


def ParseArgs():
  parser = optparse.OptionParser(description='Generate documentation and '
    'display the resulting documentation in the browser.')
  parser.add_option('--full-docs-only', '-d', dest='just_docs',
      action='store_true', default=False,
      help='Only generate documentation, no html output. (If no other '
      'options are specified, will document the SDK and all packages in the '
      'repository.)')
  parser.add_option('--package-root', '-p', dest='pkg_root',
      help='The package root for dart (default is in the build directory).',
      action='store', default=PACKAGE_ROOT)
  parser.add_option('--docgen-options', '-o',
      dest='docgen_options', help='Options to pass to docgen. If no file to '
      'document is specified, by default we generate all documenation for the '
      'SDK and all packages in the dart repository in JSON.',
      default='--json')
  parser.add_option('--gae-sdk',
      help='The path to the Google App Engine SDK. Defaults to finding the '
      'script in the PATH.', default='')
  options, _ = parser.parse_args()
  SetPackageRoot(options.pkg_root)
  return options


def AddUserDocgenOptions(sdk_cmd, docgen_options, all_docs=False):
  '''Expand the command with user specified docgen options.'''
  specified_pkg = False
  remove_append = False
  append = '--append'
  for option in docgen_options:
    if '--package-root' in option:
      specified_pkg = True
    if option == append and all_docs:
      remove_append = True
  if remove_append:
    docgen_options.remove(append)
  if not specified_pkg:
    sdk_cmd.extend(['--package-root=%s' % PACKAGE_ROOT])
  sdk_cmd.extend(docgen_options)
  return sdk_cmd


def GenerateAllDocs(docgen_options):
  '''Generate all documentation for the SDK and all packages in the repository.
  We first attempt to run the quickest path to generate all docs, but if that
  fails, we fall back on a slower option.'''
# TODO(alanknight): The --append option doesn't work properly. It overwrites
# existing files with new information. Known symptom is that it loses subclasses
# from the SDK and includes only the ones from pkg. So right now our only option
# is to do everything in one pass.
  doc_dir = join(DART_DIR, 'pkg')
  cmd_lst = [DART_EXECUTABLE, 
      '--package-root=%s' % PACKAGE_ROOT, 'docgen.dart', '--include-sdk' ]
  cmd_str = ' '.join(AddUserDocgenOptions(cmd_lst, docgen_options, True))
  # Try to run all pkg docs together at once as it's fastest.
  (return_code, _) = ExecuteCommandString('%s %s' % (cmd_str, doc_dir))
  if return_code != 0:
    # We failed to run all the pkg docs, so try to generate docs for each pkg
    # individually.
    failed_pkgs = []
    for directory in os.listdir(join(DART_DIR, 'pkg')):
      doc_dir = join(DART_DIR, 'pkg', directory)
      if (directory not in EXCLUDED_PACKAGES and
          os.path.isdir(doc_dir)):
        (return_code, output) = ExecuteCommandString('%s %s' % (cmd_str,
            doc_dir))
        if return_code != 0:
          failed_pkgs += [directory]
    print ('Generated documentation, but failed to generate documentation for '
        'the following packages, please investigate: %r' % failed_pkgs)


def ExecuteCommandString(cmd):
  '''A variant of the ExecuteCommand function that specifically executes a
  particular command string in the shell context. When you execute a string, you
  must execute in the shell.'''
  print 'Executing: %s ' % cmd
  pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
      shell=True)
  output = pipe.communicate()
  return (pipe.returncode, output)


def main():
  options = ParseArgs()
  generate_all_docs = True
  docgen_options = []
  if options.docgen_options:
    # If the user specified particular files to generate docs for, then don't
    # generate docs for everything.
    docgen_options = options.docgen_options.split()
    last_option = docgen_options[-1]
    if '=' not in last_option and exists(last_option):
      generate_all_docs = False
      docgen = [DART_EXECUTABLE, '--checked',
          '--package-root=' + PACKAGE_ROOT, join(DIRECTORY, 'docgen.dart')]
      docgen.extend(options.options.split())
      utils.ExecuteCommand(docgen)
  if generate_all_docs:
    GenerateAllDocs(docgen_options)
  if not options.just_docs:
    cwd = os.getcwd()
    try:
      utils.ExecuteCommand(['git', 'clone', '-b', 'master',
       'git://github.com/dart-lang/dartdoc-viewer.git'])
      utils.ExecuteCommand(['mv', 'docs', 'dartdoc-viewer/client/local'])
      os.chdir('dartdoc-viewer/client/')
      subprocess.call([PUB, 'install'])
      subprocess.call([DART_EXECUTABLE, 'deploy.dart'])
      if options.gae_sdk == '':
        server = subprocess.Popen(' '.join([APPSERVER_EXECUTABLE, '..']),
            shell=True)
      else:
        path_to_gae = options.gae_sdk
        if not path_to_gae.endswith(APPSERVER_EXECUTABLE):
          path_to_gae = join(path_to_gae, APPSERVER_EXECUTABLE)
        server = subprocess.Popen(join(['python', path_to_gae, '..']))
      print (
        "\nPoint your browser to the address of the 'default' server below.")
      raw_input("Press <RETURN> to terminate the server.\n\n")
      server.terminate()
    finally:
      os.chdir(cwd)
      subprocess.call(['rm', '-rf', 'dartdoc-viewer'])

if __name__ == '__main__':
  main()
