#!/usr/bin/env python3
# Copyright (c) 2012 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 json_schema import CachedLoad
from idl_schema import Load
from model import Platforms
import model
import unittest

class ModelTest(unittest.TestCase):
  def setUp(self):
    self.model = model.Model()
    self.permissions_json = CachedLoad('test/permissions.json')
    self.model.AddNamespace(self.permissions_json[0],
        'path/to/permissions.json')
    self.permissions = self.model.namespaces.get('permissions')
    self.windows_json = CachedLoad('test/windows.json')
    self.model.AddNamespace(self.windows_json[0],
        'path/to/window.json')
    self.windows = self.model.namespaces.get('windows')
    self.tabs_json = CachedLoad('test/tabs.json')
    self.model.AddNamespace(self.tabs_json[0],
        'path/to/tabs.json')
    self.tabs = self.model.namespaces.get('tabs')
    self.idl_chromeos = Load('test/idl_namespace_chromeos.idl')
    self.model.AddNamespace(self.idl_chromeos[0],
        'path/to/idl_namespace_chromeos.idl')
    self.idl_namespace_chromeos = self.model.namespaces.get(
        'idl_namespace_chromeos')
    self.idl_all_platforms = Load('test/idl_namespace_all_platforms.idl')
    self.model.AddNamespace(self.idl_all_platforms[0],
        'path/to/idl_namespace_all_platforms.idl')
    self.idl_namespace_all_platforms = self.model.namespaces.get(
        'idl_namespace_all_platforms')
    self.idl_non_specific_platforms = Load(
        'test/idl_namespace_non_specific_platforms.idl')
    self.model.AddNamespace(self.idl_non_specific_platforms[0],
        'path/to/idl_namespace_non_specific_platforms.idl')
    self.idl_namespace_non_specific_platforms = self.model.namespaces.get(
        'idl_namespace_non_specific_platforms')
    self.returns_async_json = CachedLoad('test/returns_async.json')
    self.model.AddNamespace(self.returns_async_json[0],
        'path/to/returns_async.json')
    self.returns_async = self.model.namespaces.get('returns_async')
    self.idl_returns_async_idl = Load('test/idl_returns_async.idl')
    self.model.AddNamespace(self.idl_returns_async_idl[0],
        'path/to/idl_returns_async.idl')
    self.idl_returns_async = self.model.namespaces.get('idl_returns_async')
    self.nodoc_json = CachedLoad('test/namespace_nodoc.json')
    self.model.AddNamespace(self.nodoc_json[0],
        'path/to/namespace_nodoc.json')
    self.nodoc = self.model.namespaces.get('nodoc')
    self.fakeapi_json = CachedLoad('test/namespace_fakeapi.json')
    self.model.AddNamespace(self.fakeapi_json[0],
        'path/to/namespace_fakeapi.json')
    self.fakeapi = self.model.namespaces.get('fakeapi')

    self.function_platforms_idl = Load('test/function_platforms.idl')
    self.model.AddNamespace(self.function_platforms_idl[0],
      '/path/to/function_platforms.idl')
    self.function_platforms = self.model.namespaces.get('function_platforms')

    self.function_platform_win_linux_json = CachedLoad(
        'test/function_platform_win_linux.json')
    self.model.AddNamespace(self.function_platform_win_linux_json[0],
        'path/to/function_platform_win_linux.json')
    self.function_platform_win_linux = self.model.namespaces.get(
        'function_platform_win_linux')

  def testNamespaces(self):
    self.assertEqual(12, len(self.model.namespaces))
    self.assertTrue(self.permissions)

  def testHasFunctions(self):
    self.assertEqual(["contains", "getAll", "remove", "request"],
        sorted(self.permissions.functions.keys()))

  def testHasTypes(self):
    self.assertEqual(['Tab'], list(self.tabs.types.keys()))
    self.assertEqual(['Permissions'], list(self.permissions.types.keys()))
    self.assertEqual(['Window'], list(self.windows.types.keys()))

  def testHasProperties(self):
    self.assertEqual(["active", "favIconUrl", "highlighted", "id",
        "incognito", "index", "pinned", "selected", "status", "title", "url",
        "windowId"],
        sorted(self.tabs.types['Tab'].properties.keys()))

  def testProperties(self):
    string_prop = self.tabs.types['Tab'].properties['status']
    self.assertEqual(model.PropertyType.STRING,
                      string_prop.type_.property_type)
    integer_prop = self.tabs.types['Tab'].properties['id']
    self.assertEqual(model.PropertyType.INTEGER,
                      integer_prop.type_.property_type)
    array_prop = self.windows.types['Window'].properties['tabs']
    self.assertEqual(model.PropertyType.ARRAY,
                      array_prop.type_.property_type)
    self.assertEqual(model.PropertyType.REF,
                      array_prop.type_.item_type.property_type)
    self.assertEqual('tabs.Tab', array_prop.type_.item_type.ref_type)
    object_prop = self.tabs.functions['query'].params[0]
    self.assertEqual(model.PropertyType.OBJECT,
                      object_prop.type_.property_type)
    self.assertEqual(
        ["active", "highlighted", "pinned", "status", "title", "url",
         "windowId", "windowType"],
        sorted(object_prop.type_.properties.keys()))

  def testChoices(self):
    self.assertEqual(model.PropertyType.CHOICES,
                      self.tabs.functions['move'].params[0].type_.property_type)

  def testPropertyNotImplemented(self):
    (self.permissions_json[0]['types'][0]
        ['properties']['permissions']['type']) = 'something'
    self.assertRaises(model.ParseException, self.model.AddNamespace,
        self.permissions_json[0], 'path/to/something.json')

  def testDefaultSpecifiedRedundantly(self):
    test_json = CachedLoad('test/redundant_default_attribute.json')
    self.assertRaisesRegex(
        model.ParseException,
        'Model parse exception at:\nredundantDefaultAttribute\noptionalFalse\n'
        '  in path/to/redundant_default_attribute.json\n'
        'The attribute "optional" is specified as "False", but this is the '
        'default value if the attribute is not included\. It should be '
        'removed\.',
        self.model.AddNamespace,
        test_json[0],
        'path/to/redundant_default_attribute.json')

  def testReturnsAsyncMissingParametersKey(self):
    test_json = CachedLoad('test/returns_async_missing_parameters_key.json')
    self.assertRaisesRegex(
        ValueError,
        'parameters key not specified on returns_async: '
        'returnsAsyncMissingParametersKey.asyncNoParametersKey in '
        'path/to/returns_async_missing_parameters_key.json',
        self.model.AddNamespace,
        test_json[0],
        'path/to/returns_async_missing_parameters_key.json')

  def testDescription(self):
    self.assertFalse(
        self.permissions.functions['contains'].params[0].description)
    self.assertEqual(
        'True if the extension has the specified permissions.', self.
        permissions.functions['contains'].returns_async.params[0].description)

  def testAsyncPromise(self):
    supportsPromises = self.returns_async.functions['supportsPromises']
    self.assertTrue(supportsPromises.returns_async.can_return_promise)
    doesNotSupportPromises = self.returns_async.functions[
        'doesNotSupportPromises']
    self.assertFalse(doesNotSupportPromises.returns_async.can_return_promise)
    supportsPromisesIdl = self.idl_returns_async.functions['supportsPromises']
    self.assertTrue(supportsPromisesIdl.returns_async.can_return_promise)
    doesNotSupportPromisesIdl = self.idl_returns_async.functions[
        'doesNotSupportPromises']
    self.assertFalse(doesNotSupportPromisesIdl.returns_async.can_return_promise)

  def testPropertyUnixName(self):
    param = self.tabs.functions['move'].params[0]
    self.assertEqual('tab_ids', param.unix_name)

  def testUnixName(self):
    expectations = {
      'foo': 'foo',
      'fooBar': 'foo_bar',
      'fooBarBaz': 'foo_bar_baz',
      'fooBARBaz': 'foo_bar_baz',
      'fooBAR': 'foo_bar',
      'FOO': 'foo',
      'FOOBar': 'foo_bar',
      'foo.bar': 'foo_bar',
      'foo.BAR': 'foo_bar',
      'foo.barBAZ': 'foo_bar_baz',
      'foo_Bar_Baz_box': 'foo_bar_baz_box',
      }
    for name in expectations:
      self.assertEqual(expectations[name], model.UnixName(name))

  def testCamelName(self):
    expectations = {
      'foo': 'foo',
      'fooBar': 'fooBar',
      'foo_bar_baz': 'fooBarBaz',
      'FOO_BAR': 'FOOBar',
      'FOO_bar': 'FOOBar',
      '_bar': 'Bar',
      '_bar_baz': 'BarBaz',
      'bar_': 'bar',
      'bar_baz_': 'barBaz',
      }
    for testcase, expected in expectations.items():
      self.assertEqual(expected, model.CamelName(testcase))

  def testPlatforms(self):
    self.assertEqual([Platforms.CHROMEOS],
                     self.idl_namespace_chromeos.platforms)
    self.assertEqual(
        [Platforms.CHROMEOS, Platforms.FUCHSIA, Platforms.LINUX, Platforms.MAC,
         Platforms.WIN],
        self.idl_namespace_all_platforms.platforms)
    self.assertEqual(None,
        self.idl_namespace_non_specific_platforms.platforms)

  def testInvalidNamespacePlatform(self):
    invalid_namespace_platform = Load('test/invalid_platform_namespace.idl')
    with self.assertRaises(ValueError) as context:
      self.model.AddNamespace(invalid_namespace_platform[0],
                              'path/to/something.json')
    self.assertIn('Invalid platform specified: invalid', str(context.exception))

  def testInvalidFunctionPlatform(self):
    invalid_function_platform = Load('test/invalid_function_platform.idl')
    with self.assertRaises(ValueError) as context:
      self.model.AddNamespace(invalid_function_platform[0],
                              'path/to/something.json')
    self.assertIn('Invalid platform specified: windows', str(context.exception))

  def testPlatformsOnFunctionsIDL(self):
    function_win_linux = self.function_platforms.functions['function_win_linux']
    self.assertEqual([Platforms.WIN, Platforms.LINUX],
        function_win_linux.platforms)

    function_all = self.function_platforms.functions['function_all']
    self.assertIsNone(function_all.platforms)

    function_cros = self.function_platforms.functions['function_cros']
    self.assertEqual([Platforms.CHROMEOS], function_cros.platforms)

    function_fuchsia = self.function_platforms.functions['function_fuchsia']
    self.assertEqual([Platforms.FUCHSIA], function_fuchsia.platforms)

  def testPlatformsOnFunctionsJSON(self):
    test_function = self.function_platform_win_linux.functions['test']
    self.assertEqual([Platforms.WIN, Platforms.LINUX], test_function.platforms)

  def testHasNoDoc(self):
    fakeapi_NoDocType = self.fakeapi.types['NoDocType']
    self.assertTrue(fakeapi_NoDocType.nodoc)

    fakeapi_FakeType = self.fakeapi.types['FakeType']
    selected_property = fakeapi_FakeType.properties['nodocProperty']
    self.assertTrue(selected_property.nodoc)

    nodocMethod_method = self.fakeapi.functions['nodocMethod']
    self.assertTrue(nodocMethod_method.nodoc)

    onFooNoDoc_event = self.fakeapi.events['onFooNoDoc']
    self.assertTrue(onFooNoDoc_event.nodoc)

    onFoo_event = self.fakeapi.events['onFoo']
    self.assertFalse(onFoo_event.nodoc)

    self.assertTrue(self.nodoc.nodoc, 'Namespace should also be marked nodoc')
    nodoc_ValidType = self.nodoc.types['ValidType']
    self.assertFalse(nodoc_ValidType.nodoc)

if __name__ == '__main__':
  unittest.main()
