#
#  Copyright (C) 2019 Bloomberg Finance LP
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU Lesser General Public
#  License as published by the Free Software Foundation; either
#  version 2 of the License, or (at your option) any later version.
#
#  This library 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
#  Lesser General Public License for more details.
#
#  You should have received a copy of the GNU Lesser General Public
#  License along with this library. If not, see <http://www.gnu.org/licenses/>.
#
#  Authors:
#        Raoul Hidalgo Charman <raoul.hidalgocharman@codethink.co.uk>
#

# Pylint doesn't play well with fixtures and dependency injection from pytest
# pylint: disable=redefined-outer-name

import os
import pytest

from buildstream.testing.runcli import cli  # pylint: disable=unused-import
from buildstream import _yaml

DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "project")


@pytest.mark.datafiles(DATA_DIR)
def test_patch_sources_cached_1(cli, datafiles):
    project_dir = str(datafiles)

    res = cli.run(project=project_dir, args=["build", "source-with-patches-1.bst"])
    res.assert_success()

    # as we have a local, patch, local config, the first local and patch should
    # be cached together, and the last local on it's own
    source_dir = os.path.join(project_dir, 'cache', 'cas', 'refs', 'heads', '@sources')

    assert len(os.listdir(os.path.join(source_dir, 'patch'))) == 1
    assert len(os.listdir(os.path.join(source_dir, 'local'))) == 2


@pytest.mark.datafiles(DATA_DIR)
def test_patch_sources_cached_2(cli, datafiles):
    project_dir = str(datafiles)

    res = cli.run(project=project_dir, args=["build", "source-with-patches-2.bst"])
    res.assert_success()

    # As everything is before the patch it should all be cached together
    source_dir = os.path.join(project_dir, 'cache', 'cas', 'refs', 'heads', '@sources')

    assert len(os.listdir(os.path.join(source_dir, 'patch'))) == 1


@pytest.mark.datafiles(DATA_DIR)
def test_sources_without_patch(cli, datafiles):
    project_dir = str(datafiles)

    res = cli.run(project=project_dir, args=["build", "source-without-patches.bst"])
    res.assert_success()

    # No patches so everything should be cached seperately
    source_dir = os.path.join(project_dir, 'cache', 'cas', 'refs', 'heads', '@sources')

    assert len(os.listdir(os.path.join(source_dir, 'local'))) == 3


@pytest.mark.datafiles(DATA_DIR)
def test_source_cache_key(cli, datafiles):
    project_dir = str(datafiles)

    file_path = os.path.join(project_dir, 'files')
    file_url = 'file://' + file_path
    element_path = os.path.join(project_dir, 'elements')
    element_name = 'key_check.bst'
    element = {
        'kind': 'import',
        'sources': [
            {
                'kind': 'remote',
                'url': os.path.join(file_url, 'bin-files', 'usr', 'bin', 'hello'),
                'directory': 'usr/bin'
            }, {
                'kind': 'remote',
                'url': os.path.join(file_url, 'dev-files', 'usr', 'include', 'pony.h'),
                'directory': 'usr/include'
            }, {
                'kind': 'patch',
                'path': 'files/hello-patch.diff'
            }
        ]
    }
    _yaml.dump(element, os.path.join(element_path, element_name))

    res = cli.run(project=project_dir, args=["source", "track", element_name])
    res.assert_success()

    res = cli.run(project=project_dir, args=["build", element_name])
    res.assert_success()

    # Should have one source ref
    patch_refs = os.path.join(project_dir, 'cache', 'cas', 'refs', 'heads', '@sources', 'patch')
    assert len(os.listdir(patch_refs)) == 1

    # modify hello-patch file and check tracking updates refs
    with open(os.path.join(file_path, 'dev-files', 'usr', 'include', 'pony.h'), 'a') as f:
        f.write("\nappending nonsense")

    res = cli.run(project=project_dir, args=["source", "track", element_name])
    res.assert_success()
    assert "Found new revision: " in res.stderr

    res = cli.run(project=project_dir, args=["source", "fetch", element_name])
    res.assert_success()

    # We should have a new source ref
    assert len(os.listdir(patch_refs)) == 2
