#!/usr/bin/python

# Copyright (c) 2014, 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.

"""
Buildbot steps for src tarball generation and debian package generation

Package up the src of the dart repo and create a debian package.
Archive tarball and debian package to google cloud storage.
"""

import os
import re
import sys

import bot
import bot_utils

utils = bot_utils.GetUtils()

HOST_OS = utils.GuessOS()
SRC_BUILDER = r'linux-distribution-support-(debian_wheezy|ubuntu_precise)'

def SrcConfig(name, is_buildbot):
  """Returns info for the current buildbot based on the name of the builder.

  Currently, since we only run this on linux, this is just:
  - mode: always "release"
  - system: always "linux"
  """
  src_pattern = re.match(SRC_BUILDER, name)
  if not src_pattern:
    return None
  return bot.BuildInfo('none', 'none', 'release', 'linux',
                       builder_tag=src_pattern.group(1))

def ArchiveArtifacts(tarfile, builddir, channel, linux_system):
  namer = bot_utils.GCSNamer(channel=channel)
  gsutil = bot_utils.GSUtil()
  revision = utils.GetSVNRevision()
  # Archive the src tar to the src dir
  remote_tarfile = '/'.join([namer.src_directory(revision),
                             os.path.basename(tarfile)])
  gsutil.upload(tarfile, remote_tarfile, public=True)
  # Archive all files except the tar file to the linux packages dir
  for entry in os.listdir(builddir):
    full_path = os.path.join(builddir, entry)
    # We expect a flat structure, not subdirectories
    assert(os.path.isfile(full_path))
    if full_path != tarfile:
      package_dir = namer.linux_packages_directory(revision, linux_system)
      remote_file = '/'.join([package_dir,
                              os.path.basename(entry)])
      gsutil.upload(full_path, remote_file, public=True)

def InstallFromDep(builddir):
  for entry in os.listdir(builddir):
    if entry.endswith("_amd64.deb"):
      path = os.path.join(builddir, entry)
      Run(['sudo', 'dpkg', '-i', path])

def UninstallDart():
  Run(['sudo', 'dpkg', '-r', 'dart'])

def CreateDartTestFile(tempdir):
  filename = os.path.join(tempdir, 'test.dart')
  with open(filename, 'w') as f:
    f.write('import "dart:collection";\n\n')
    f.write('void main() {\n')
    f.write('  print("Hello world");\n')
    f.write('}')
  return filename

def Run(args):
  print "Running: %s" % ' '.join(args)
  sys.stdout.flush()
  bot.RunProcess(args)

def TestInstallation(assume_installed=True):
  paths = ['/usr/bin/dart']
  for tool in ['dart2js', 'pub', 'dart', 'dartanalyzer']:
    paths.append(os.path.join('/usr/lib/dart/bin', tool))
  for path in paths:
    if os.path.exists(path):
      if not assume_installed:
        print 'Assumed not installed, found %s' % path
        sys.exit(1)
    else:
      if assume_installed:
        print 'Assumed installed, but could not find %s' % path
        sys.exit(1)

def SrcSteps(build_info):
  # We always clobber the bot, to not leave old tarballs and packages
  # floating around the out dir.
  bot.Clobber(force=True)

  version = utils.GetVersion()
  builddir = os.path.join(bot_utils.DART_DIR,
                          utils.GetBuildDir(HOST_OS),
                          'src_and_installation')

  if not os.path.exists(builddir):
    os.makedirs(builddir)
  tarfilename = 'dart-%s.tar.gz' % version
  tarfile = os.path.join(builddir, tarfilename)

  with bot.BuildStep('Validating linux system'):
    print 'Validating that we are on %s' % build_info.builder_tag
    args = ['cat', '/etc/os-release']
    (stdout, stderr, exitcode) = bot_utils.run(args)
    if exitcode != 0:
      print "Could not find linux system, exiting"
      sys.exit(1)

    if build_info.builder_tag == "debian_wheezy":
      if not "wheezy" in stdout:
        print "Trying to build debian bits on a non debian system"
        print "You can't fix this, please contact ricow@ or whesse@"
        sys.exit(1)
    if build_info.builder_tag == "ubuntu_precise":
      if not "precise" in stdout:
        print "Trying to build ubuntu bits on a non ubuntu system"
        print "You can't fix this, please contact ricow@ or whesse@"
        sys.exit(1)

  with bot.BuildStep('Create src tarball'):
    print 'Building src tarball'
    Run([sys.executable, './tools/create_tarball.py',
         '--tar_filename', tarfile])

    print 'Building Debian packages'
    Run([sys.executable, './tools/create_debian_packages.py',
         '--tar_filename', tarfile,
         '--out_dir', builddir])

  with bot.BuildStep('Sanity check installation'):
    if os.path.exists('/usr/bin/dart'):
      print "Dart already installled, removing"
      UninstallDart()
    TestInstallation(assume_installed=False)

    InstallFromDep(builddir)
    TestInstallation(assume_installed=True)

    # We build the runtime target to get everything we need to test the
    # standalone target.
    Run([sys.executable, './tools/build.py', '-mrelease', '-ax64', 'runtime'])
    # Copy in the installed binary to avoid poluting /usr/bin (and having to
    # run as root)
    Run(['cp', '/usr/bin/dart', 'out/ReleaseX64/dart'])

    # We currently can't run the testing script on wheezy since the checked in
    # binary is built on precise, see issue 18742
    if (build_info.builder_tag == 'ubuntu_precise'):
      Run([sys.executable, './tools/test.py', '-ax64',
          '--mode=release', 'standalone'])

    # Sanity check dart2js and the analyzer against a hello world program
    with utils.TempDir() as temp_dir:
      test_file = CreateDartTestFile(temp_dir)
      Run(['/usr/lib/dart/bin/dart2js', test_file])
      Run(['/usr/lib/dart/bin/dartanalyzer', test_file])
      Run(['/usr/lib/dart/bin/dart', test_file])

    # Sanity check that pub can start up and print the version
    Run(['/usr/lib/dart/bin/pub', '--version'])

    UninstallDart()
    TestInstallation(assume_installed=False)

  with bot.BuildStep('Upload artifacts'):
    bot_name, _ = bot.GetBotName()
    channel = bot_utils.GetChannelFromName(bot_name)
    if channel != bot_utils.Channel.BLEEDING_EDGE:
     ArchiveArtifacts(tarfile, builddir, channel, build_info.builder_tag)
    else:
      print 'Not uploading artifacts on bleeding edge'

if __name__ == '__main__':
  # We pass in None for build_step to avoid building the sdk.
  bot.RunBot(SrcConfig, SrcSteps, build_step=None)
