# encoding: utf-8

# This file is part of CycloneDX Python Lib
#
# 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.
#
# SPDX-License-Identifier: Apache-2.0
# Copyright (c) OWASP Foundation. All Rights Reserved.
import json
from typing import Any, Dict

from . import BaseParser
from ..model import ExternalReference, ExternalReferenceType, HashType
from ..model.component import Component


class PipEnvParser(BaseParser):

    def __init__(self, pipenv_contents: str) -> None:
        super().__init__()

        pipfile_lock_contents = json.loads(pipenv_contents)
        pipfile_default: Dict[str, Dict[str, Any]] = pipfile_lock_contents.get('default') or {}

        for (package_name, package_data) in pipfile_default.items():
            c = Component(
                name=package_name,
                version=str(package_data.get('version') or 'unknown').lstrip('='),
            )
            if package_data.get('index') == 'pypi' and isinstance(package_data.get('hashes'), list):
                # Add download location with hashes stored in Pipfile.lock
                for pip_hash in package_data['hashes']:
                    ext_ref = ExternalReference(
                        reference_type=ExternalReferenceType.DISTRIBUTION,
                        url=c.get_pypi_url(),
                        comment='Distribution available from pypi.org'
                    )
                    ext_ref.add_hash(HashType.from_composite_str(pip_hash))
                    c.add_external_reference(ext_ref)

            self._components.append(c)


class PipEnvFileParser(PipEnvParser):

    def __init__(self, pipenv_lock_filename: str) -> None:
        with open(pipenv_lock_filename) as r:
            super(PipEnvFileParser, self).__init__(pipenv_contents=r.read())
