# Copyright (C) 2018 The Meme Factory, Inc.  http://www.meme.com/

# This file is part of PGWUI_Upload.
#
# This program is free software: you can redistribute it and/or
# modify it under the terms of the GNU Affero General Public License
# as published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public
# License along with this program.  If not, see
# <http://www.gnu.org/licenses/>.
#

# Karl O. Pinc <kop@meme.com>

import pytest
from pyramid.threadlocal import get_current_request
from pgwui_common.__init__ import includeme as pgwui_common_includeme
from pgwui_core import form_constants
from pgwui_upload.__init__ import includeme as pgwui_upload_includeme
from pgwui_upload.views import upload

# Activiate our pytest plugin
pytest_plugins = ("pgwui",)


# Constants
CHANGED_RESPONSE = {
    'db': 'somedb',
    'db_changed': True,
    'filename': 'file',
    'lines': 5,
    'null_rep': 'NULL',
    'table': 'sometable',
    'trim_upload': form_constants.CHECKED,
    'upload_null': form_constants.CHECKED,
    'user': 'someuser',
}


# Helper classes

class MockUploadEngine():
    def __init__(self, run_result):
        self.run_result = run_result

    def run(self):
        return self.run_result


class MockTableUploadHandler():
    def __init__(self, *args):
        pass


class MockLogger():
    def __init__(self):
        self.info_called = False

    def info(self, *args):
        self.info_called = True


# Fixtures

@pytest.fixture
def isolate_upload_view(monkeypatch):
    '''Keep upload_view() from calling anything

    Also, have isolate_upload_view(response)
    cause UploadEngine to return the supplied "response".
    '''
    def run(response):
        # Have the pyramid.view.view_config decorator do nothing
        monkeypatch.setattr(upload, 'view_config',
                            lambda **kwargs: (lambda func: func))

        def upload_engine(*args):
            return MockUploadEngine(response)

        monkeypatch.setattr(upload, 'UploadEngine', upload_engine)
        monkeypatch.setattr(
            upload, 'TableUploadHandler', MockTableUploadHandler)

        mock_logger = MockLogger()
        monkeypatch.setattr(upload, 'log', mock_logger)
        return mock_logger

    return run


# Tests

# upload_view()

def test_upload_view_db_not_changed(monkeypatch, isolate_upload_view):
    '''When the db did not change nothing logs'''

    response = {'db_changed': False}
    mock_logger = isolate_upload_view(response)
    result = upload.upload_view(None)

    assert result == response
    assert mock_logger.info_called is False


def test_upload_view_db_changed_csv(monkeypatch, isolate_upload_view):
    '''When the db did change from CSV input something logs'''

    response = CHANGED_RESPONSE
    response['csv_checked'] = form_constants.CHECKED

    mock_logger = isolate_upload_view(response)
    result = upload.upload_view(None)

    assert result == response
    assert mock_logger.info_called is True


def test_upload_view_db_changed_no_csv(
        pyramid_request_config, isolate_upload_view):
    '''When the db did change from not-CSV input something logs'''

    response = CHANGED_RESPONSE
    response['csv_checked'] = form_constants.UNCHECKED

    mock_logger = isolate_upload_view(response)

    pgwui_common_includeme(pyramid_request_config)
    pgwui_upload_includeme(pyramid_request_config)
    request = get_current_request()
    result = upload.upload_view(request)

    assert result == response
    assert mock_logger.info_called is True
