import json

import pytest
import responses

import datarobot as dr
from datarobot.utils import camelize
from tests.utils import request_body_to_json


class TestHDFSCreate(object):
    @pytest.fixture
    def hdfs_create_response(self, unittest_endpoint, async_url):
        mysql_create_url = '{}/{}/'.format(unittest_endpoint, 'hdfsProjects')
        responses.add(
            responses.POST,
            mysql_create_url,
            body='',
            status=202,
            content_type='application/json',
            adding_headers={'Location': async_url}
        )

    @responses.activate
    @pytest.mark.usefixtures('project_creation_responses',
                             'hdfs_create_response')
    def test_create_hdfs_minimum(self):
        dr.Project.create_from_hdfs(url='hdfs://webhdfs.com/directory/file.csv')
        create_body = request_body_to_json(responses.calls[0].request)
        assert create_body['url'] == 'hdfs://webhdfs.com/directory/file.csv'

    @responses.activate
    @pytest.mark.usefixtures('project_creation_responses',
                             'hdfs_create_response')
    def test_create_hdfs_all_options(self):
        dr.Project.create_from_hdfs(url='hdfs://webhdfs.com/directory/file.csv',
                                    port=9999,
                                    project_name='HDFS Project',
                                    max_wait=100)
        create_body = request_body_to_json(responses.calls[0].request)
        assert create_body['url'] == 'hdfs://webhdfs.com/directory/file.csv'
        assert create_body['port'] == 9999
        assert create_body['projectName'] == 'HDFS Project'


class TestDataSourceCreate(object):
    @pytest.fixture
    def data_source_create_response(self, unittest_endpoint, async_url):
        project_create_url = '{}/{}'.format(unittest_endpoint, dr.Project._path)
        responses.add(
            responses.POST,
            project_create_url,
            body='',
            status=202,
            content_type='application/json',
            adding_headers={'Location': async_url}
        )

    @pytest.fixture
    def data_source(self):
        return dr.DataSource('5acc8437ec8d670001ba16bf')

    @responses.activate
    @pytest.mark.usefixtures('project_creation_responses',
                             'data_source_create_response')
    def test_create_from_data_source_id(self):
        username = 'test_user'
        password = 'megasuperubersecretpassword'
        data_source_id = '5acc8437ec8d670001ba16bf'
        project_name = 'data source project'
        dr.Project.create_from_data_source(data_source_id, username, password,
                                           project_name=project_name)
        create_body = request_body_to_json(responses.calls[0].request)
        assert create_body == {
            'user': username,
            'password': password,
            'dataSourceId': data_source_id,
            'projectName': project_name
        }


class TestDatasetCreate(object):
    @responses.activate
    @pytest.mark.usefixtures('project_creation_responses')
    def test_create_from_dataset_use_defaults(self, project_collection_url,
                                              project_without_target_json):
        dataset_id = 'abc123'
        project = dr.Project.create_from_dataset(dataset_id)

        create_body = request_body_to_json(responses.calls[0].request)
        assert create_body == {'datasetId': dataset_id}
        assert responses.calls[0].request.url == project_collection_url

        response_json = json.loads(project_without_target_json)
        assert project.id == response_json['id']
        assert project.project_name == response_json['projectName']
        assert project.file_name == response_json['fileName']
        assert project.stage == response_json['stage']

    @responses.activate
    @pytest.mark.usefixtures('project_creation_responses')
    @pytest.mark.parametrize('param_name,param_value', [
        ('dataset_version_id', '20gjkfdlj'),
        ('project_name', 'my cool name'),
        ('user', 'that guy over there'),
        ('password', 'my voice is my passport'),
        ('credential_id', '12345'),
        ('use_kerberos', True)
    ])
    def test_create_from_dataset_using_params(self, param_name, param_value):
        dataset_id = 'abc123'
        dr.Project.create_from_dataset(dataset_id, **{param_name: param_value})
        create_body = request_body_to_json(responses.calls[0].request)
        assert create_body == {'datasetId': dataset_id, camelize(param_name): param_value}
