#
# Copyright (c) nexB Inc. and others. All rights reserved.
# purldb is a trademark of nexB Inc.
# SPDX-License-Identifier: Apache-2.0
# See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
# See https://github.com/aboutcode-org/purldb for support or download.
# See https://aboutcode.org for more information about nexB OSS projects.
#

import json
import os
from collections import OrderedDict
from unittest.mock import patch

from packageurl import PackageURL

from minecode import miners
from minecode.miners import dockerhub
from minecode.tests import FIXTURES_REGEN
from minecode.utils_test import JsonBasedTesting
from minecode.utils_test import mocked_requests_get


class DockerHubTest(JsonBasedTesting):
    test_data_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), "testfiles")


class DockerHubVistorTest(DockerHubTest):
    def test_searching_condition(self):
        combinations = dockerhub.get_search_conditions()
        expected_file = self.get_test_loc("dockerhub/conditions_expected")
        self.check_expected_results(combinations, expected_file, regen=FIXTURES_REGEN)

    def test_seeds(self):
        seed = dockerhub.DockerHubSeed()
        seeds = list(seed.get_seeds())
        expected_file = self.get_test_loc("dockerhub/seeds_expected")
        self.check_expected_results(seeds, expected_file, regen=FIXTURES_REGEN)

    def test_visit_dockerhub_exlpore_page(self):
        uri = "https://hub.docker.com/explore/?page=1"
        test_loc = self.get_test_loc("dockerhub/Explore_DockerHub_Page1.html")
        with patch("requests.get") as mock_http_get:
            mock_http_get.return_value = mocked_requests_get(uri, test_loc)
            uris, _, _ = dockerhub.DockHubExplorePageVisitor(uri)
        expected_loc = self.get_test_loc("dockerhub/visitor_explore_page1_expected")
        self.check_expected_uris(uris, expected_loc, regen=FIXTURES_REGEN)

    def test_visit_dockerhub_project(self):
        uri = "https://hub.docker.com/_/elixir/"
        test_loc = self.get_test_loc("dockerhub/library_elixir.html")
        with patch("requests.get") as mock_http_get:
            mock_http_get.return_value = mocked_requests_get(uri, test_loc)
            _, data, _ = dockerhub.DockHubProjectHTMLVisitor(uri)

        result = json.loads(data, object_pairs_hook=OrderedDict)
        expected_file = self.get_test_loc("dockerhub/visitor_library_elixir_expected")
        self.check_expected_results(result, expected_file, regen=FIXTURES_REGEN)

    def test_visit_dockerhub_search_api(self):
        uri = "https://index.docker.io/v1/search?q=1a&n=100&page=2"
        test_loc = self.get_test_loc("dockerhub/search.json")
        with patch("requests.get") as mock_http_get:
            mock_http_get.return_value = mocked_requests_get(uri, test_loc)
            uris, _, _ = dockerhub.DockHubLibraryRESTJsonVisitor(uri)
        expected_loc = self.get_test_loc("dockerhub/visitor_search_expected")
        self.check_expected_uris(uris, expected_loc, regen=FIXTURES_REGEN)


class DockerHubMapperTest(DockerHubTest):
    def test_build_packages_fromjson(self):
        with open(self.get_test_loc("dockerhub/elixir.json")) as dockerhub_metadata:
            metadata = dockerhub_metadata.read()
        packages = miners.dockerhub.build_packages_from_jsonfile(
            metadata, "https://registry.hub.docker.com/v2/repositories/library"
        )
        packages = [p.to_dict() for p in packages]
        expected_loc = self.get_test_loc("dockerhub/expected_dockerhubmapper.json")
        self.check_expected_results(packages, expected_loc, regen=FIXTURES_REGEN)


class DockerHubMapTest(DockerHubTest):
    def test_build_package_data_dockerhub1(self):
        with open(self.get_test_loc("dockerhub/nginx.json")) as dockerhub_metadata:
            metadata = json.load(dockerhub_metadata)
            summary = metadata["summary"]
            tags_metadata = metadata["tags_metadata"]

        package_url = PackageURL.from_string("pkg:docker/nginx@stable-perl")

        packages = miners.dockerhub.build_package_data(summary, tags_metadata, package_url)

        packages = [p.to_dict() for p in packages]
        expected_loc = self.get_test_loc("dockerhub/expected-nginx1.json")
        self.check_expected_results(packages, expected_loc, regen=FIXTURES_REGEN)

    def test_build_package_data_dockerhub2(self):
        with open(self.get_test_loc("dockerhub/nginx.json")) as dockerhub_metadata:
            metadata = json.load(dockerhub_metadata)
            summary = metadata["summary"]
            tags_metadata = metadata["tags_metadata"]

        package_url = PackageURL.from_string(
            "pkg:docker/nginx@sha256:3d8957cb61d0223de2ab1aa2ec91d29796eb82a81cdcc1e968c090c29606d648"
        )

        packages = miners.dockerhub.build_package_data(summary, tags_metadata, package_url)

        packages = [p.to_dict() for p in packages]
        expected_loc = self.get_test_loc("dockerhub/expected-nginx2.json")
        self.check_expected_results(packages, expected_loc, regen=FIXTURES_REGEN)
