#!/usr/bin/env python
#
# Copyright (c) 2012, 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.

# Dart SDK promote tools.

import imp
import optparse
import os
import subprocess
import sys
import time
import urllib
import bots.bot_utils as bot_utils

from os.path import join

DART_PATH = os.path.abspath(os.path.join(__file__, '..', '..'))
DRY_RUN = False


def BuildOptions():
    usage = """usage: %prog promote [options]
  where:
    promote - Will promote builds from raw/signed locations to release
              locations.

    Example: Promote version 2.5.0 on the stable channel:
        python editor/build/promote.py promote --channel=stable --version=2.5.0
  """

    result = optparse.OptionParser(usage=usage)

    group = optparse.OptionGroup(result, 'Promote',
                                 'options used to promote code')
    group.add_option(
        '--revision',
        '--version',
        help='The version to promote',
        action='store')
    group.add_option(
        '--channel',
        type='string',
        help='The channel to promote.',
        default=None)
    group.add_option(
        "--dry", help='Dry run', default=False, action="store_true")
    result.add_option_group(group)

    return result


def main():
    parser = BuildOptions()
    (options, args) = parser.parse_args()

    def die(msg):
        print msg
        parser.print_help()
        sys.exit(1)

    if not args:
        die('At least one command must be specified')

    if args[0] == 'promote':
        command = 'promote'
        if options.revision is None:
            die('You must specify a --revision to specify which revision to promote'
               )

        # Make sure options.channel is a valid
        if not options.channel:
            die('Specify --channel=beta/dev/stable')
        if options.channel not in bot_utils.Channel.ALL_CHANNELS:
            die('You must supply a valid channel to --channel to promote')
    else:
        die('Invalid command specified: {0}.  See help below'.format(args[0]))

    if options.dry:
        global DRY_RUN
        DRY_RUN = True
    if command == 'promote':
        _PromoteDartArchiveBuild(options.channel, options.revision)


def UpdateDocs():
    try:
        print 'Updating docs'
        url = "http://api.dartlang.org/docs/releases/latest/?force_reload=true"
        f = urllib.urlopen(url)
        f.read()
        print 'Successfully updated api docs'
    except Exception as e:
        print 'Could not update api docs, please manually update them'
        print 'Failed with: %s' % e


def _PromoteDartArchiveBuild(channel, revision):
    # These namer objects will be used to create GCS object URIs. For the
    # structure we use, please see tools/bots/bot_utils.py:GCSNamer
    raw_namer = bot_utils.GCSNamer(channel, bot_utils.ReleaseType.RAW)
    signed_namer = bot_utils.GCSNamer(channel, bot_utils.ReleaseType.SIGNED)
    release_namer = bot_utils.GCSNamer(channel, bot_utils.ReleaseType.RELEASE)

    def promote(to_revision):

        def safety_check_on_gs_path(gs_path, revision, channel):
            if not (revision != None and len(channel) > 0 and
                    ('%s' % revision) in gs_path and channel in gs_path):
                raise Exception(
                    "InternalError: Sanity check failed on GS URI: %s" %
                    gs_path)

        def exists(gs_path):
            (_, _, exit_code) = Gsutil(['ls', gs_path], throw_on_error=False)
            # gsutil will exit 0 if the "directory" exists
            return exit_code == 0

        # Google cloud storage has read-after-write, read-after-update,
        # and read-after-delete consistency, but not list after delete consistency.
        # Because gsutil uses list to figure out if it should do the unix styly
        # copy to or copy into, this means that if the directory is reported as
        # still being there (after it has been deleted) gsutil will copy
        # into the directory instead of to the directory.
        def wait_for_delete_to_be_consistent_with_list(gs_path):
            if DRY_RUN:
                return
            while exists(gs_path):
                time.sleep(1)

        def remove_gs_directory(gs_path):
            safety_check_on_gs_path(gs_path, to_revision, channel)
            # Only delete existing directories
            if exists(gs_path):
                Gsutil(['-m', 'rm', '-R', '-f', gs_path])
                wait_for_delete_to_be_consistent_with_list(gs_path)

        # Copy the signed sdk directory.
        from_loc = signed_namer.sdk_directory(revision)
        to_loc = release_namer.sdk_directory(to_revision)
        remove_gs_directory(to_loc)
        has_signed = exists(from_loc)
        if has_signed:
            Gsutil(['-m', 'cp', '-a', 'public-read', '-R', from_loc, to_loc])
            # Because gsutil copies differently to existing directories, we need
            # to use the base directory for the next recursive copy.
            to_loc = release_namer.base_directory(to_revision)

        # Copy the unsigned sdk directory without clobbering signed files.
        from_loc = raw_namer.sdk_directory(revision)
        Gsutil(['-m', 'cp', '-n', '-a', 'public-read', '-R', from_loc, to_loc])

        # Copy api-docs zipfile.
        from_loc = raw_namer.apidocs_zipfilepath(revision)
        to_loc = release_namer.apidocs_zipfilepath(to_revision)
        Gsutil(['-m', 'cp', '-a', 'public-read', from_loc, to_loc])

        # Copy wheezy linux deb and src packages.
        from_loc = raw_namer.linux_packages_directory(revision)
        to_loc = release_namer.linux_packages_directory(to_revision)
        remove_gs_directory(to_loc)
        Gsutil(['-m', 'cp', '-a', 'public-read', '-R', from_loc, to_loc])

        # Copy VERSION file.
        from_loc = raw_namer.version_filepath(revision)
        to_loc = release_namer.version_filepath(to_revision)
        Gsutil(['cp', '-a', 'public-read', from_loc, to_loc])

    promote(revision)
    promote('latest')


def Gsutil(cmd, throw_on_error=True):
    gsutilTool = join(DART_PATH, 'third_party', 'gsutil', 'gsutil')
    command = [sys.executable, gsutilTool] + cmd
    if DRY_RUN:
        print "DRY runnning: %s" % command
        return (None, None, 0)
    return bot_utils.run(command, throw_on_error=throw_on_error)


if __name__ == '__main__':
    sys.exit(main())
