# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cross-language tests for JSON serialization."""

from absl.testing import absltest
from absl.testing import parameterized

from tink.proto import tink_pb2
from util import supported_key_types
from util import testing_servers


def setUpModule():
  testing_servers.start()


def tearDownModule():
  testing_servers.stop()


def _keyset_proto(keyset: bytes) -> tink_pb2.Keyset:
  keyset_proto = tink_pb2.Keyset()
  keyset_proto.ParseFromString(keyset)
  # We sort the keys, since we want keysets to be considered equal even if the
  # keys are in different order.
  keyset_proto.key.sort(key=lambda k: k.key_id)
  return keyset_proto


def _is_equal_keyset(keyset1: bytes, keyset2: bytes) -> bool:
  """Checks if two keyset are equal, and have the exact same keydata.value."""
  # Keydata.value are serialized protos. This serialization is usually not
  # deterministic, as it is a unsorted list of key value pairs.
  # But since JSON serialization does not change keyset.value, we can simply
  # require these values to be exactly the same in this test. In other tests,
  # this might be too strict.
  return _keyset_proto(keyset1) == _keyset_proto(keyset2)


class JsonTest(parameterized.TestCase):

  def test_is_equal_keyset(self):
    keyset1 = tink_pb2.Keyset()
    key11 = keyset1.key.add()
    key11.key_id = 21
    key12 = keyset1.key.add()
    key12.key_id = 42
    keyset2 = tink_pb2.Keyset()
    key21 = keyset2.key.add()
    key21.key_id = 42
    key22 = keyset2.key.add()
    key22.key_id = 21
    self.assertTrue(_is_equal_keyset(keyset1.SerializeToString(),
                                     keyset2.SerializeToString()))

  def test_is_not_equal_keyset(self):
    keyset1 = tink_pb2.Keyset()
    key11 = keyset1.key.add()
    key11.key_id = 21
    key12 = keyset1.key.add()
    key12.key_id = 42
    keyset2 = tink_pb2.Keyset()
    key3 = keyset2.key.add()
    key3.key_id = 21
    self.assertFalse(_is_equal_keyset(keyset1.SerializeToString(),
                                      keyset2.SerializeToString()))

  def assertEqualKeyset(self, keyset1: bytes, keyset2: bytes):
    if not _is_equal_keyset(keyset1, keyset2):
      self.fail('these keysets are not equal: \n%s\n \n%s\n'
                % (_keyset_proto(keyset1), _keyset_proto(keyset2)))

  @parameterized.parameters(
      supported_key_types.test_cases(supported_key_types.ALL_KEY_TYPES))
  def test_to_from_json(self, key_template_name, supported_langs):
    self.assertNotEmpty(supported_langs)
    key_template = supported_key_types.KEY_TEMPLATE[key_template_name]
    # Take the first supported language to generate the keyset.
    keyset = testing_servers.new_keyset(supported_langs[0], key_template)
    for to_lang in supported_langs:
      json_keyset = testing_servers.keyset_to_json(to_lang, keyset)
      for from_lang in supported_langs:
        keyset2 = testing_servers.keyset_from_json(from_lang, json_keyset)
        self.assertEqualKeyset(keyset, keyset2)


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