#
# Copyright (c) 2019 Intel Corporation
#
# 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.
#

from click.testing import CliRunner

from cli_text_consts import ModelExportCmdTexts as Texts
from commands.model.common import workflow_description
from commands.model.export import export
from platform_resources.workflow import ArgoWorkflow, QUEUED_PHASE

FEM_NAME = "EXPORT_1"
SEM_NAME = "EXPORT_2"
FEM_PARAMETERS = "PARAMS_1"
SEM_PARAMETERS = "PARAMS_2"

FEM_START_DATE = '2000-01-01'
FEM_NAMESPACE = 'test-namespace'

TEST_AGROWORKFLOW = ArgoWorkflow(name=FEM_NAME, started_at=FEM_START_DATE, finished_at=None,
                                 namespace=FEM_NAMESPACE, phase=None)

TWO_MODEL_OUTPUT = [workflow_description(name=FEM_NAME, parameters=FEM_PARAMETERS),
                    workflow_description(name=SEM_NAME, parameters=SEM_PARAMETERS)]


def setup_mocks(mocker):
    mocker.patch('commands.model.export.get_kubectl_current_context_namespace',
                 return_value='fake-namespace')
    mocker.patch('platform_resources.workflow.ArgoWorkflow.from_yaml',
                 return_value=mocker.MagicMock())
    mocker.patch('platform_resources.workflow.ArgoWorkflow.get',
                 return_value=TEST_AGROWORKFLOW)
    mocker.patch('os.listdir', return_value=['openvino.yaml', 'tensorflow.yaml', 'some_other_file'])
    mocker.patch('commands.model.export.NAUTAConfigMap', return_value=mocker.MagicMock(registry='fake-addr'))
    mocker.patch('commands.model.export.Config')
    mocker.patch('os.path.isdir', return_value=True)


def test_export(mocker):
    setup_mocks(mocker)
    result = CliRunner().invoke(export, ["/fake/path", "openvino"])

    assert result.exit_code == 0
    assert "Successfully created export workflow" in result.output
    assert QUEUED_PHASE in result.output
    assert FEM_NAME in result.output
    assert FEM_START_DATE in result.output
    assert FEM_NAMESPACE in result.output


def test_export_inexistent_format(mocker):
    setup_mocks(mocker)

    result = CliRunner().invoke(export, ["/fake/path", "bad"])

    assert result.exit_code == 2
    assert "Format: bad does not exist. Choose from:" in result.output


def test_export_failure(mocker):
    setup_mocks(mocker)
    mocker.patch('platform_resources.workflow.ArgoWorkflow.from_yaml',
                 return_value=mocker.MagicMock(create=lambda: RuntimeError))

    result = CliRunner().invoke(export, ["/fake/path", "openvino"])

    assert result.exit_code == 1
    assert "Failed to create export workflow" in result.output


def test_export_list(mocker):
    mocker.patch("commands.model.export.get_list_of_workflows", return_value=TWO_MODEL_OUTPUT)

    result = CliRunner().invoke(export, ["formats"])

    assert FEM_NAME in result.output
    assert SEM_NAME in result.output
    assert FEM_PARAMETERS in result.output
    assert SEM_PARAMETERS in result.output


def test_export_list_error(mocker):
    mocker.patch("commands.model.export.get_list_of_workflows", side_effect=RuntimeError)

    result = CliRunner().invoke(export, ["formats"])

    assert Texts.EXPORT_LIST_ERROR_MSG in result.output


def test_export_missing_format(mocker):
    setup_mocks(mocker)
    result = CliRunner().invoke(export, ["wrong-option"])

    assert Texts.MISSING_EXPORT_FORMAT.format(formats=["openvino", "tensorflow"]) in result.output

[((32, 20, 33, 69), 'platform_resources.workflow.ArgoWorkflow', 'ArgoWorkflow', (), '', False, 'from platform_resources.workflow import ArgoWorkflow, QUEUED_PHASE\n'), ((35, 20, 35, 82), 'commands.model.common.workflow_description', 'workflow_description', (), '', False, 'from commands.model.common import workflow_description\n'), ((36, 20, 36, 82), 'commands.model.common.workflow_description', 'workflow_description', (), '', False, 'from commands.model.common import workflow_description\n'), ((107, 11, 107, 81), 'cli_text_consts.ModelExportCmdTexts.MISSING_EXPORT_FORMAT.format', 'Texts.MISSING_EXPORT_FORMAT.format', (), '', True, 'from cli_text_consts import ModelExportCmdTexts as Texts\n'), ((54, 13, 54, 24), 'click.testing.CliRunner', 'CliRunner', ({}, {}), '()', False, 'from click.testing import CliRunner\n'), ((67, 13, 67, 24), 'click.testing.CliRunner', 'CliRunner', ({}, {}), '()', False, 'from click.testing import CliRunner\n'), ((78, 13, 78, 24), 'click.testing.CliRunner', 'CliRunner', ({}, {}), '()', False, 'from click.testing import CliRunner\n'), ((87, 13, 87, 24), 'click.testing.CliRunner', 'CliRunner', ({}, {}), '()', False, 'from click.testing import CliRunner\n'), ((98, 13, 98, 24), 'click.testing.CliRunner', 'CliRunner', ({}, {}), '()', False, 'from click.testing import CliRunner\n'), ((105, 13, 105, 24), 'click.testing.CliRunner', 'CliRunner', ({}, {}), '()', False, 'from click.testing import CliRunner\n')]