# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

from recipe_engine.types import freeze

DEPS = [
    'build',
    'depot_tools/git',
    'recipe_engine/json',
    'recipe_engine/path',
    'perf_dashboard',
    'recipe_engine/context',
    'recipe_engine/platform',
    'recipe_engine/properties',
    'recipe_engine/python',
    'recipe_engine/raw_io',
    'recipe_engine/step',
]

# Constants
ANDROID_TOOLS_GIT = 'https://chromium.googlesource.com/android_tools'
ANDROID_NDK_GIT = 'https://chromium.googlesource.com/android_ndk'
TEST_FILES_URL = 'http://downloads.webmproject.org/test_data/libvpx'

# Device root is a special folder on the device which we have permissions to
# read / write
DEVICE_ROOT = '/data/local/tmp'

# TODO (joshualitt) the configure script is messed up so we need a relative
# path.  Essentially, it must be using argv[0] when invoking some of the
# scripts in the libvpx directory
CONFIGURE_PATH_REL = './libvpx/configure'

BUILDER_TO_DEVICE = freeze({
  'Nexus 5 Builder' : 'nexus_5',
  'Nexus 7 Builder': 'nexus_7'
})

from recipe_engine.recipe_api import Property

PROPERTIES = {
  'libvpx_git_url': Property(),
  'buildername': Property(),
}

def RunSteps(api, libvpx_git_url, buildername):
  # Paths and other constants
  build_root = api.path['start_dir']

  # Android tools DEPS
  android_tools_root = build_root.join('android_tools')
  adb = android_tools_root.join('sdk', 'platform-tools', 'adb')
  ndk_root = build_root.join('android_ndk')

  # libvpx paths
  libvpx_root = build_root.join('libvpx')
  test_data = build_root.join('test_data')

  api.python.inline(
      'clean_build', r"""
          import os, sys, shutil
          root = sys.argv[1]
          nuke_dirs = sys.argv[2:]
          for fname in os.listdir(root):
            path = os.path.join(root, fname)
            if os.path.isfile(path):
              os.unlink(path)
            elif fname in nuke_dirs:
              shutil.rmtree(path)
      """, args=[build_root, 'libs', 'obj', 'armeabi-v7a'])

  # Checkout android_tools, android_ndk and libvpx.  NDK and SDK are required
  # to build libvpx for android
  api.git.checkout(
      ANDROID_TOOLS_GIT, dir_path=android_tools_root, recursive=True)
  api.git.checkout(
      ANDROID_NDK_GIT, dir_path=ndk_root)
  api.git.checkout(
      libvpx_git_url, dir_path=libvpx_root, recursive=True)

  # The dashboards need a number to assign to this build for ordering purposes.
  with api.context(cwd=libvpx_root):
    step_result = api.git('number', stdout=api.raw_io.output_text())
  libvpx_revision_number = step_result.stdout

  api.step(
      'configure', [
          CONFIGURE_PATH_REL, '--disable-examples', '--disable-install-docs',
          '--disable-install-srcs', '--enable-unit-tests', '--enable-webm-io',
          '--disable-vp8-encoder', '--enable-vp9-encoder',
          '--enable-decode-perf-tests', '--enable-external-build',
          '--enable-vp8-decoder', '--enable-vp9-decoder',
          '--enable-encode-perf-tests', '--disable-realtime-only',
          '--sdk-path=%s' % ndk_root, '--target=armv7-android-gcc'])

  # NDK requires NDK_PROJECT_PATH environment variable to be defined
  with api.context(env={'NDK_PROJECT_PATH': build_root}):
    api.step(
        'ndk-build', [
            ndk_root.join('ndk-build'),
            'APP_BUILD_SCRIPT=%s'
                % libvpx_root.join('test', 'android', 'Android.mk'),
            'APP_ABI=armeabi-v7a', 'APP_PLATFORM=android-14',
            'APP_OPTIM=release', 'APP_STL=gnustl_static'])

  test_root = libvpx_root.join('test')
  api.python(
      'get_files', test_root.join('android', 'get_files.py'),
      args=[
          '-i', test_root.join('test-data.sha1'),
          '-o', test_data, '-u', TEST_FILES_URL])

  api.build.python(
      'transfer_files',
      api.package_repo_resource('scripts', 'slave', 'android',
                             'transfer_files.py'),
      args=[adb, DEVICE_ROOT, test_data])

  lib_root = build_root.join('libs', 'armeabi-v7a')
  api.step('push_so', [adb, 'push', lib_root, DEVICE_ROOT])

  step_result = api.python.inline(
      'adb_wrap', r"""
          import sys, subprocess, time
          out = open(sys.argv[1], "w")
          p = subprocess.Popen(sys.argv[2:], stdout=out)
          while p.poll() is None:
              print "Still working"
              time.sleep(60)
          print "done"
          sys.exit(p.returncode)
      """, args=[api.raw_io.output_text(), adb, 'shell',
          'LD_LIBRARY_PATH=' + DEVICE_ROOT,
          'LIBVPX_TEST_DATA_PATH=' + DEVICE_ROOT, DEVICE_ROOT +
          '/vpx_test', '--gtest_filter=-*Large*'])

  step_result = api.python(
      'scrape_logs',
      libvpx_root.join('test', 'android', 'scrape_gtest_log.py'),
      args=['--output-json', api.json.output()],
      stdin=api.raw_io.input_text(step_result.raw_io.output_text))

  data = step_result.json.output
  # Data is json array in the format as follows:
  # videoName: name
  # threadCount: #ofthreads
  # framesPerSecond: fps
  points = []
  device = BUILDER_TO_DEVICE[buildername]

  #TODO(martiniss) convert loop
  for i in data:
    if i["type"] == "encode_perf_test":
      # Two data points for encoder tests, FPS and minPsnr
      testname = "libvpx/encode/perf_test/fps/" + device + "/"
      testname = testname + i["videoName"] + "_" + str(i["speed"])
      p = api.perf_dashboard.get_skeleton_point(
          testname,
          libvpx_revision_number,
          i["framesPerSecond"],
          bot=api.m.properties["bot_id"])
      p['units'] = "fps"
      points.append(p)

      #minPsnr
      testname = "libvpx/encode/perf_test/minPsnr/" + device + "/"
      testname = testname + i["videoName"] + "_" + str(i["speed"])
      p = api.perf_dashboard.get_skeleton_point(
          testname,
          libvpx_revision_number,
          i["minPsnr"],
          bot=api.m.properties["bot_id"])
      p['units'] = "dB"
      points.append(p)
    else:
      testname = "libvpx/decode/perf_test/" + device + "/"
      testname = testname + i["videoName"] + "_" + str(i["threadCount"])
      p = api.perf_dashboard.get_skeleton_point(
          testname,
          libvpx_revision_number,
          i["framesPerSecond"],
          bot=api.m.properties["bot_id"])
      p['units'] = "fps"
      points.append(p)

  api.perf_dashboard.set_default_config()
  api.perf_dashboard.add_point(points)

def GenTests(api):
  # Right now we just support linux, but one day we will have mac and windows
  # as well
  yield (
    api.test('basic_linux_64') +
    api.properties(
        libvpx_git_url='https://chromium.googlesource.com/webm/libvpx',
        bot_id='libvpx-bot', buildername='Nexus 5 Builder',
        mastername='client.libvpx', buildnumber='75') +
    api.step_data('git number', stdout=api.raw_io.output_text('42')) +
    api.step_data('adb_wrap',
        api.raw_io.output_text("This is text with json inside normally")) +
    api.step_data('scrape_logs', api.json.output(
            [
                {
                    "type" : "decode_perf_test",
                    "decodeTimeSecs": 29.344307,
                    "framesPerSecond": 609.82868,
                    "threadCount": 1,
                    "totalFrames": 17895,
                    "version": "v1.3.0-2045-g38c2d37",
                    "videoName": "vp90-2-bbb_426x240_tile_1x1_180kbps.webm"
                },
                {
                    "type" : "encode_perf_test",
                    "encodeTimeSecs": 56.277676,
                    "speed" : 5,
                    "minPsnr" : 43.5,
                    "framesPerSecond": 317.976883,
                    "threadCount": 2,
                    "totalFrames": 17895,
                    "version": "v1.3.0-2045-g38c2d37",
                    "videoName": "vp90-2-bbb_640x360_tile_1x2_337kbps.webm"
                 }
            ])))
