#!/usr/bin/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 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


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('}\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()
    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'])
