#!/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
import hashlib
import os
import shutil
import sys
import tempfile
import unittest
import six

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

# pylint: disable=useless-object-inheritance


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'
INTERFACE_API_VERSION_FILENAME = './android/interface_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=[six.StringIO(), six.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.exe_path = os.path.join(REPOSITORY_ROOT, 'out')
    self.temp_dir = tempfile.mkdtemp(dir=self.exe_path)
    os.chdir(self.temp_dir)
    os.mkdir('android')
    with open(INTERFACE_API_VERSION_FILENAME, 'w') \
         as interface_api_version_file:
      interface_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(INTERFACE_API_VERSION_FILENAME, 'r') \
         as interface_api_version_file:
      interface_api_version = interface_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 = hashlib.md5()
    api_hash.update(api.encode('utf-8'))
    self.assertEqual(api_stamp, 'Stamp: %s' % api_hash.hexdigest())

    return [return_code == 0, output, api, interface_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'])
