#!/usr/bin/env python
# Copyright 2016 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.

"""api_static_checks_unittest.py - Unittests for api_static_checks.py"""


import contextlib
from cStringIO import StringIO
import md5
import os
import shutil
import sys
import tempfile
import unittest

REPOSITORY_ROOT = os.path.abspath(os.path.join(
    os.path.dirname(__file__), '..', '..', '..'))

sys.path.append(os.path.join(REPOSITORY_ROOT, 'components'))
from cronet.tools import api_static_checks  # pylint: disable=wrong-import-position


ERROR_PREFIX_CHECK_API_CALLS = (
"""ERROR: Found the following calls from implementation classes through
       API classes.  These could fail if older API is used that
       does not contain newer methods.  Please call through a
       wrapper class from VersionSafeCallbacks.
""")


ERROR_PREFIX_UPDATE_API = (
"""ERROR: This API was modified or removed:
             """)


ERROR_SUFFIX_UPDATE_API = (
"""

       Cronet API methods and classes cannot be modified.
""")


CHECK_API_VERSION_PREFIX = (
"""DO NOT EDIT THIS FILE, USE update_api.py TO UPDATE IT

""")


API_FILENAME = './android/api.txt'
API_VERSION_FILENAME = './android/api_version.txt'


@contextlib.contextmanager
def capture_output():
  # A contextmanger that collects the stdout and stderr of wrapped code

  oldout,olderr = sys.stdout, sys.stderr
  try:
    out=[StringIO(), StringIO()]
    sys.stdout,sys.stderr = out
    yield out
  finally:
    sys.stdout,sys.stderr = oldout, olderr
    out[0] = out[0].getvalue()
    out[1] = out[1].getvalue()


class ApiStaticCheckUnitTest(unittest.TestCase):
  def setUp(self):
    self.temp_dir = tempfile.mkdtemp()
    os.chdir(self.temp_dir)
    os.mkdir('android')
    with open(API_VERSION_FILENAME, 'w') as api_version_file:
      api_version_file.write('0')
    with open(API_FILENAME, 'w') as api_file:
      api_file.write('}\nStamp: 7d9d25f71cb8a5aba86202540a20d405\n')
    shutil.copytree(os.path.dirname(__file__), 'tools')


  def tearDown(self):
    shutil.rmtree(self.temp_dir)


  def make_jar(self, java, class_name):
    # Compile |java| wrapped in a class named |class_name| to a jar file and
    # return jar filename.

    java_filename = class_name + '.java'
    class_filenames = class_name + '*.class'
    jar_filename = class_name + '.jar'

    with open(java_filename, 'w') as java_file:
      java_file.write('public class %s {' % class_name)
      java_file.write(java)
      java_file.write('}')
    os.system('javac %s' % java_filename)
    os.system('jar cf %s %s' % (jar_filename, class_filenames))
    return jar_filename


  def run_check_api_calls(self, api_java, impl_java):
    test = self
    class MockOpts(object):
      def __init__(self):
        self.api_jar = test.make_jar(api_java, 'Api')
        self.impl_jar = [test.make_jar(impl_java, 'Impl')]
    opts = MockOpts()
    with capture_output() as return_output:
      return_code = api_static_checks.check_api_calls(opts)
    return [return_code, return_output[0]]


  def test_check_api_calls_success(self):
    # Test simple classes with functions
    self.assertEqual(self.run_check_api_calls(
        'void a(){}', 'void b(){}'), [True, ''])
    # Test simple classes with functions calling themselves
    self.assertEqual(self.run_check_api_calls(
        'void a(){} void b(){a();}', 'void c(){} void d(){c();}'), [True, ''])


  def test_check_api_calls_failure(self):
    # Test static call
    self.assertEqual(self.run_check_api_calls(
        'public static void a(){}', 'void b(){Api.a();}'),
        [False, ERROR_PREFIX_CHECK_API_CALLS + 'Impl/b -> Api/a:()V\n'])
    # Test virtual call
    self.assertEqual(self.run_check_api_calls(
        'public void a(){}', 'void b(){new Api().a();}'),
        [False, ERROR_PREFIX_CHECK_API_CALLS + 'Impl/b -> Api/a:()V\n'])


  def run_check_api_version(self, java):
    OUT_FILENAME = 'out.txt'
    return_code = os.system('./tools/update_api.py --api_jar %s > %s' %
        (self.make_jar(java, 'Api'), OUT_FILENAME))
    with open(API_FILENAME, 'r') as api_file:
      api = api_file.read()
    with open(API_VERSION_FILENAME, 'r') as api_version_file:
      api_version = api_version_file.read()
    with open(OUT_FILENAME, 'r') as out_file:
      output = out_file.read()

    # Verify stamp
    api_stamp = api.split('\n')[-2]
    stamp_length = len('Stamp: 78418460c193047980ae9eabb79293f2\n')
    api = api[:-stamp_length]
    api_hash = md5.new()
    api_hash.update(api)
    self.assertEquals(api_stamp, 'Stamp: %s' % api_hash.hexdigest())

    return [return_code == 0, output, api, api_version]


  def test_update_api_success(self):
    # Test simple new API
    self.assertEqual(self.run_check_api_version(
        'public void a(){}'),
        [True, '', CHECK_API_VERSION_PREFIX + """public class Api {
  public Api();
  public void a();
}
""", '1'])
    # Test version number not increased when API not changed
    self.assertEqual(self.run_check_api_version(
        'public void a(){}'),
        [True, '', CHECK_API_VERSION_PREFIX + """public class Api {
  public Api();
  public void a();
}
""", '1'])
    # Test acceptable API method addition
    self.assertEqual(self.run_check_api_version(
        'public void a(){} public void b(){}'),
        [True, '', CHECK_API_VERSION_PREFIX + """public class Api {
  public Api();
  public void a();
  public void b();
}
""", '2'])
    # Test version number not increased when API not changed
    self.assertEqual(self.run_check_api_version(
        'public void a(){} public void b(){}'),
        [True, '', CHECK_API_VERSION_PREFIX + """public class Api {
  public Api();
  public void a();
  public void b();
}
""", '2'])
    # Test acceptable API class addition
    self.assertEqual(self.run_check_api_version(
        'public void a(){} public void b(){} public class C {}'),
        [True, '', CHECK_API_VERSION_PREFIX + """public class Api$C {
  public Api$C(Api);
}
public class Api {
  public Api();
  public void a();
  public void b();
}
""", '3'])
    # Test version number not increased when API not changed
    self.assertEqual(self.run_check_api_version(
        'public void a(){} public void b(){} public class C {}'),
        [True, '', CHECK_API_VERSION_PREFIX + """public class Api$C {
  public Api$C(Api);
}
public class Api {
  public Api();
  public void a();
  public void b();
}
""", '3'])


  def test_update_api_failure(self):
    # Create a simple new API
    self.assertEqual(self.run_check_api_version(
        'public void a(){}'),
        [True, '', CHECK_API_VERSION_PREFIX + """public class Api {
  public Api();
  public void a();
}
""", '1'])
    # Test removing API method not allowed
    self.assertEqual(self.run_check_api_version(''),
        [False, ERROR_PREFIX_UPDATE_API + 'public void a();'
            + ERROR_SUFFIX_UPDATE_API,
            CHECK_API_VERSION_PREFIX + """public class Api {
  public Api();
  public void a();
}
""", '1'])
    # Test modifying API method not allowed
    self.assertEqual(self.run_check_api_version(
        'public void a(int x){}'),
        [False, ERROR_PREFIX_UPDATE_API + 'public void a();'
            + ERROR_SUFFIX_UPDATE_API,
            CHECK_API_VERSION_PREFIX + """public class Api {
  public Api();
  public void a();
}
""", '1'])
