# -*- coding: utf-8 -*-

""" tests.test_signing

Unit tests for conda-content-trust/conda_content_trust/signing.py


 NOTE that much of the signing module is currently tested in
   test_authentication.py instead.  Some unit tests are missing.


Run the tests this way:
    pytest tests/test_signing.py

"""

# Python2 Compatibility
from __future__ import absolute_import, division, print_function, unicode_literals

import os, os.path
import shutil
import copy

from conda_content_trust.common import *
from conda_content_trust.authentication import *
from conda_content_trust.signing import *

import pytest

# Some REGRESSION test data.
REG__KEYPAIR_NAME = 'keytest_old'
REG__PRIVATE_BYTES = b'\xc9\xc2\x06\r~\r\x93al&T\x84\x0bI\x83\xd0\x02!\xd8\xb6\xb6\x9c\x85\x01\x07\xdat\xb4!h\xf97'
REG__PRIVATE_HEX = 'c9c2060d7e0d93616c2654840b4983d00221d8b6b69c850107da74b42168f937'
REG__PUBLIC_BYTES = b"\x01=\xddqIb\x86m\x12\xba[\xae'?\x14\xd4\x8c\x89\xcf\x07s\xde\xe2\xdb\xf6\xd4V\x1eR\x1c\x83\xf7"
REG__PUBLIC_HEX = '013ddd714962866d12ba5bae273f14d48c89cf0773dee2dbf6d4561e521c83f7'
# Signature is over b'123456\x067890' using key REG__PRIVATE_BYTES.
REG__SIGNATURE = b'\xb6\xda\x14\xa1\xedU\x9e\xbf\x01\xb3\xa9\x18\xc9\xb8\xbd\xccFM@\x87\x99\xe8\x98\x84C\xe4}9;\xa4\xe5\xfd\xcf\xdaau\x04\xf5\xcc\xc0\xe7O\x0f\xf0F\x91\xd3\xb8"\x7fD\x1dO)*\x1f?\xd7&\xd6\xd3\x1f\r\x0e'
REG__HASHED_VAL = b'string to hash\n'
REG__HASH_HEX = '73aec9a93f4beb41a9bad14b9d1398f60e78ccefd97e4eb7d3cf26ba71dbe0ce'
#REG__HASH_BYTES = b's\xae\xc9\xa9?K\xebA\xa9\xba\xd1K\x9d\x13\x98\xf6\x0ex\xcc\xef\xd9~N\xb7\xd3\xcf&\xbaq\xdb\xe0\xce'
REG__REPODATA_HASHMAP = {
    "noarch/current_repodata.json": "908724926552827ab58dfc0bccba92426cec9f1f483883da3ff0d8664e18c0fe",
    "noarch/repodata.json": "908724926552827ab58dfc0bccba92426cec9f1f483883da3ff0d8664e18c0fe",
    "noarch/repodata_from_packages.json": "908724926552827ab58dfc0bccba92426cec9f1f483883da3ff0d8664e18c0fe",
    "osx-64/current_repodata.json": "8120fb07a6a8a280ffa2b89fb2fbb89484823d0b0357ff0cfa7c333352b2faa2",
    "osx-64/repodata.json": "8120fb07a6a8a280ffa2b89fb2fbb89484823d0b0357ff0cfa7c333352b2faa2",
    "osx-64/repodata_from_packages.json": "8120fb07a6a8a280ffa2b89fb2fbb89484823d0b0357ff0cfa7c333352b2faa2"
}
REG__TEST_TIMESTAMP = '2019-10-01T00:00:00Z'
REG__TEST_EXPIRY_DATE = '2025-01-01T10:30:00Z'
REG__EXPECTED_UNSIGNED_REPODATA_VERIFY = {
    'type': 'repodata_verify', 'timestamp': REG__TEST_TIMESTAMP,
    'metadata_spec_version': '0.1.0', 'expiration': REG__TEST_EXPIRY_DATE,
    'secured_files': {
        'noarch/current_repodata.json': '908724926552827ab58dfc0bccba92426cec9f1f483883da3ff0d8664e18c0fe',
        'noarch/repodata.json': '908724926552827ab58dfc0bccba92426cec9f1f483883da3ff0d8664e18c0fe',
        'noarch/repodata_from_packages.json': '908724926552827ab58dfc0bccba92426cec9f1f483883da3ff0d8664e18c0fe',
        'osx-64/current_repodata.json': '8120fb07a6a8a280ffa2b89fb2fbb89484823d0b0357ff0cfa7c333352b2faa2',
        'osx-64/repodata.json': '8120fb07a6a8a280ffa2b89fb2fbb89484823d0b0357ff0cfa7c333352b2faa2',
        'osx-64/repodata_from_packages.json': '8120fb07a6a8a280ffa2b89fb2fbb89484823d0b0357ff0cfa7c333352b2faa2'}
}
REG__EXPECTED_REGSIGNED_REPODATA_VERIFY = {
    # Re-sign this if its data changes: it's signed!
    'type': 'repodata_verify', 'timestamp': '2019-10-01T00:00:00Z',
    'metadata_spec_version': '0.1.0', 'expiration': '2025-01-01T10:30:00Z',
    'secured_files': {
        'noarch/current_repodata.json': '908724926552827ab58dfc0bccba92426cec9f1f483883da3ff0d8664e18c0fe',
        'noarch/repodata.json': '908724926552827ab58dfc0bccba92426cec9f1f483883da3ff0d8664e18c0fe',
        'noarch/repodata_from_packages.json': '908724926552827ab58dfc0bccba92426cec9f1f483883da3ff0d8664e18c0fe',
        'osx-64/current_repodata.json': '8120fb07a6a8a280ffa2b89fb2fbb89484823d0b0357ff0cfa7c333352b2faa2',
        'osx-64/repodata.json': '8120fb07a6a8a280ffa2b89fb2fbb89484823d0b0357ff0cfa7c333352b2faa2',
        'osx-64/repodata_from_packages.json': '8120fb07a6a8a280ffa2b89fb2fbb89484823d0b0357ff0cfa7c333352b2faa2'}
}
REG__REPODATA_SAMPLE_FNAME = 'tests/repodata_sample.json'
REG__REPODATA_SAMPLE_TEMP_FNAME = 'tests/repodata_sample_temp.json'



# def test_serialize_and_sign():
#     raise(NotImplementedError()
#             '⚠️ These tests are currently implemented in '
#             'test_authentication.py instead.'))


# def test_sign_signable():
#     raise(NotImplementedError(
#             '⚠️ These tests are currently implemented in '
#             'test_authentication.py instead.'))

# def test_wrap_as_signable():
#     raise(NotImplementedError(
#             '⚠️ This function is tested in multiple modules, but '
#             'a unit test should be constructed from those tests.'))


def test_sign_all_in_repodata():

    public = PublicKey.from_hex(REG__PUBLIC_HEX)

    # Make a test copy of the repodata sample, since we're going to
    # update it.
    if os.path.exists(REG__REPODATA_SAMPLE_TEMP_FNAME):
        os.remove(REG__REPODATA_SAMPLE_TEMP_FNAME)
    shutil.copy(
            REG__REPODATA_SAMPLE_FNAME,
            REG__REPODATA_SAMPLE_TEMP_FNAME)

        # grab data and use it to compare to what we produce in a bit

    repodata = load_metadata_from_file(REG__REPODATA_SAMPLE_FNAME)

    sign_all_in_repodata(REG__REPODATA_SAMPLE_TEMP_FNAME, REG__PRIVATE_HEX)

    repodata_signed = load_metadata_from_file(REG__REPODATA_SAMPLE_TEMP_FNAME)

    # Ensure that the rest of repodata is unchanged.
    repodata_signed_stripped = copy.deepcopy(repodata_signed)
    del repodata_signed_stripped['signatures']
    assert repodata_signed_stripped == repodata
    del repodata_signed_stripped

    # Make sure there is one signature entry for every artifact entry, and no
    # mystery entries.
    assert repodata['packages'].keys() == repodata_signed['signatures'].keys()

    for artifact_name in repodata['packages']:
        # There's a signature "by" this key listed for every artifact.
        assert REG__PUBLIC_HEX in repodata_signed['signatures'][artifact_name]
        # The signature is valid.
        verify_signature(
                # signature, (supposed) key, data that was (supposedly) signed
                repodata_signed['signatures'][artifact_name][REG__PUBLIC_HEX]['signature'],
                public,
                canonserialize(repodata['packages'][artifact_name]))


    # if os.path.exists(REG__REPODATA_SAMPLE_TEMP_FNAME):
    #     os.remove(REG__REPODATA_SAMPLE_TEMP_FNAME)



