import base64
import hashlib
import os
import urllib.parse

import pytest
import requests

SPECIAL_CHARS = '!#$%&+-^_`;[]{}+='


@pytest.mark.parametrize(
    "path,file_name",
    [
        ('', 'some.file'),
        ('/toto', 'some.file'),
        ('/toto/tata', 'some.file'),
        ('/toto', 'some.other'),
        ('/%s' % SPECIAL_CHARS, '%(spe)s.%(spe)s' % {'spe': SPECIAL_CHARS}),
    ],
)
def test_uploadfile(cmisclient, cmis_connector, cmis_tmpdir, tmpdir, monkeypatch, path, file_name):
    result_filename = 'result.file'
    monkeypatch.chdir(tmpdir)
    orig_file = tmpdir.join(file_name)
    with orig_file.open('wb') as f:
        f.write(os.urandom(1024))
    url = urllib.parse.urljoin(cmis_connector, 'uploadfile')
    with orig_file.open('rb') as f:
        file_b64_content = base64.b64encode(f.read())
    response = requests.post(
        url,
        json={
            "path": cmis_tmpdir + path,
            "file": {"content": file_b64_content, "filename": file_name, "content_type": "image/jpeg"},
        },
    )
    assert response.status_code == 200
    resp_data = response.json()
    assert resp_data['err'] == 0
    assert resp_data['data']['properties']['cmis:name'] == file_name
    doc = cmisclient.defaultRepository.getObject(resp_data['data']['properties']['cmis:objectId'])
    with open(result_filename, 'wb') as f:
        result = doc.getContentStream()
        f.write(result.read())
        result.close()
    with open(result_filename, 'rb') as f:
        result_sha1 = hashlib.sha1()
        result_sha1.update(f.read())
    with open(file_name, 'rb') as f:
        orig_sha1 = hashlib.sha1()
        orig_sha1.update(f.read())
    assert orig_sha1.digest() == result_sha1.digest()


def test_uploadfile_conflict(cmisclient, cmis_connector, cmis_tmpdir, tmpdir, monkeypatch):
    url = urllib.parse.urljoin(cmis_connector, 'uploadfile')
    file_b64_content = base64.b64encode('file_content')
    response = requests.post(
        url,
        json={
            "path": cmis_tmpdir + '/uploadconflict',
            "file": {"content": file_b64_content, "filename": 'some.file', "content_type": "image/jpeg"},
        },
    )
    assert response.status_code == 200
    resp_data = response.json()
    assert resp_data['err'] == 0
    file_b64_content = base64.b64encode('other_file_content')
    response = requests.post(
        url,
        json={
            "path": cmis_tmpdir + '/uploadconflict',
            "file": {"content": file_b64_content, "filename": 'some.file', "content_type": "image/jpeg"},
        },
    )
    assert response.status_code == 200
    resp_data = response.json()
    assert resp_data['err'] == 1
    assert resp_data['err_desc'].startswith("update conflict")
