# Copyright 2018 Red Hat, Inc.
#
# 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.

import json
import urllib.parse

testinfra_hosts = ['etherpad99.opendev.org']


def test_etherpad_listening(host):
    etherpad = host.socket("tcp://127.0.0.1:9001")
    assert etherpad.is_listening

def test_etherpad_robots(host):
    cmd = host.run('curl --insecure '
                   '--resolve etherpad.opendev.org:443:127.0.0.1 '
                   'https://etherpad.opendev.org/robots.txt')
    assert 'Disallow: /' in cmd.stdout

def test_etherpad_logs(host):
    etherpad_log_file = host.file('/var/log/containers/docker-etherpad.log')
    assert etherpad_log_file.exists
    assert etherpad_log_file.contains('Etherpad is running')

    mariadb_log_file = host.file('/var/log/containers/docker-mariadb.log')
    assert mariadb_log_file.exists
    assert mariadb_log_file.contains('mariadbd: ready for connections.')

def _get_bearer_token(host):
    # Get a Beaer token via Oauth2 negotiation for API interaction
    cmd = host.run('grep \'"client_secret":\' /etc/etherpad/settings.json |'
                   ' sed -e \'s/\\s\\+"client_secret": "\\(.*\\)",/\\1/\'')
    secret = cmd.stdout.strip()
    cmd = host.run('curl --data grant_type=client_credentials '
                   '--data client_id=api_admin --data client_secret="%s" '
                   'http://localhost:9001/oidc/token' % secret)
    ret = json.loads(cmd.stdout)
    assert ret['token_type'] == 'Bearer'
    token = ret['access_token']
    return token

def test_etherpad_4_byte_utf8(host):
    # The 🖖 utf8 character is a four byte character. This test ensures we
    # can set that value in a pad and get it back out again. This test both
    # general functionality as well as proper database setup for four byte
    # utf8 chars
    teststr = '🖖 Live long and prosper 🖖'
    urlstr = urllib.parse.quote(teststr)

    token = _get_bearer_token(host)

    # Test the API works and that 4 byte chars are happy.
    cmd = host.run('curl -H "Authorization: Bearer %s" '
                   '"http://localhost:9001/api/1/createPad?'
                   'padID=testing"' % token)
    assert '"code":0' in cmd.stdout
    assert '"message":"ok"' in cmd.stdout
    cmd = host.run('curl -H "Authorization: Bearer %s" '
                   '"http://localhost:9001/api/1/setText?'
                   'padID=testing&text=%s"' % (token, urlstr))
    assert '"code":0' in cmd.stdout
    assert '"message":"ok"' in cmd.stdout
    cmd = host.run('curl -H "Authorization: Bearer %s" '
                   '"http://localhost:9001/api/1/getText?'
                   'padID=testing"' % token)
    assert '"code":0' in cmd.stdout
    assert '"message":"ok"' in cmd.stdout
    assert teststr in cmd.stdout

def test_etherpad_delete_pad(host):
    urlstr = urllib.parse.quote('test pad delete string')
    token = _get_bearer_token(host)

    cmd = host.run('curl -H "Authorization: Bearer %s" '
                   '"http://localhost:9001/api/1/createPad?'
                   'padID=testing_delete"' % token)
    assert '"code":0' in cmd.stdout
    assert '"message":"ok"' in cmd.stdout
    cmd = host.run('curl -H "Authorization: Bearer %s" '
                   '"http://localhost:9001/api/1/setText?'
                   'padID=testing_delete&text=%s"' % (token, urlstr))
    assert '"code":0' in cmd.stdout
    assert '"message":"ok"' in cmd.stdout
    cmd = host.run('curl -H "Authorization: Bearer %s" '
                   '"http://localhost:9001/api/1.2.1/listAllPads"' % token)
    assert '"code":0' in cmd.stdout
    assert '"message":"ok"' in cmd.stdout
    pads = json.loads(cmd.stdout)['data']['padIDs']
    assert 'testing_delete' in pads
    cmd = host.run('curl -H "Authorization: Bearer %s" '
                   '"http://localhost:9001/api/1/deletePad?'
                   'padID=testing_delete"' % token)
    assert '"code":0' in cmd.stdout
    assert '"message":"ok"' in cmd.stdout
    cmd = host.run('curl -H "Authorization: Bearer %s" '
                   '"http://localhost:9001/api/1.2.1/listAllPads"' % token)
    assert '"code":0' in cmd.stdout
    assert '"message":"ok"' in cmd.stdout
    pads = json.loads(cmd.stdout)['data']['padIDs']
    assert 'testing_delete' not in pads

def test_etherpad_restore_pad(host):
    firststr = urllib.parse.quote('first')
    secondstr = urllib.parse.quote('second')
    token = _get_bearer_token(host)

    cmd = host.run('curl -H "Authorization: Bearer %s" '
                   '"http://localhost:9001/api/1/createPad?'
                   'padID=testing_restore"' % token)
    assert '"code":0' in cmd.stdout
    assert '"message":"ok"' in cmd.stdout
    cmd = host.run('curl -H "Authorization: Bearer %s" '
                   '"http://localhost:9001/api/1/setText?'
                   'padID=testing_restore&text=%s"' % (token, firststr))
    assert '"code":0' in cmd.stdout
    assert '"message":"ok"' in cmd.stdout
    cmd = host.run('curl -H "Authorization: Bearer %s" '
                   '"http://localhost:9001/api/1/setText?'
                   'padID=testing_restore&text=%s"' % (token, secondstr))
    assert '"code":0' in cmd.stdout
    assert '"message":"ok"' in cmd.stdout
    cmd = host.run('curl -H "Authorization: Bearer %s" '
                   '"http://localhost:9001/api/1/getText?'
                   'padID=testing_restore"' % token)
    assert '"code":0' in cmd.stdout
    assert '"message":"ok"' in cmd.stdout
    assert firststr not in cmd.stdout
    assert secondstr in cmd.stdout
    cmd = host.run('curl -H "Authorization: Bearer %s" '
                   '"http://localhost:9001/api/1/getRevisionsCount?'
                   'padID=testing_restore"' % token)
    assert '"code":0' in cmd.stdout
    assert '"message":"ok"' in cmd.stdout
    revisions = json.loads(cmd.stdout)['data']['revisions']
    old_rev = urllib.parse.quote(str(revisions - 1))
    cmd = host.run('curl -H "Authorization: Bearer %s" '
                   '"http://localhost:9001/api/1.2.11/restoreRevision?'
                   'padID=testing_restore&rev=%s"' % (token, old_rev))
    assert '"code":0' in cmd.stdout
    assert '"message":"ok"' in cmd.stdout
    cmd = host.run('curl -H "Authorization: Bearer %s" '
                   '"http://localhost:9001/api/1/getText?'
                   'padID=testing_restore"' % token)
    assert '"code":0' in cmd.stdout
    assert '"message":"ok"' in cmd.stdout
    assert firststr in cmd.stdout
    assert secondstr not in cmd.stdout