# 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]

  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"
                 }
            ])))
