# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.

import hashlib

from libcloud.utils.py3 import hexadigits
from libcloud.utils.py3 import b
from libcloud.utils.py3 import base64_decode_string

__all__ = [
    "get_pubkey_openssh_fingerprint",
    "get_pubkey_ssh2_fingerprint",
    "get_pubkey_comment",
]

try:
    from cryptography.hazmat.backends import default_backend
    from cryptography.hazmat.primitives import serialization

    cryptography_available = True
except ImportError:
    cryptography_available = False


def _to_md5_fingerprint(data):
    hashed = hashlib.md5(data).digest()
    return ":".join(hexadigits(hashed))


def get_pubkey_openssh_fingerprint(pubkey):
    # We import and export the key to make sure it is in OpenSSH format
    if not cryptography_available:
        raise RuntimeError("cryptography is not available")
    public_key = serialization.load_ssh_public_key(b(pubkey), backend=default_backend())
    pub_openssh = public_key.public_bytes(
        encoding=serialization.Encoding.OpenSSH,
        format=serialization.PublicFormat.OpenSSH,
    )[
        7:
    ]  # strip ssh-rsa prefix
    return _to_md5_fingerprint(base64_decode_string(pub_openssh))


def get_pubkey_ssh2_fingerprint(pubkey):
    # This is the format that EC2 shows for public key fingerprints in its
    # KeyPair mgmt API
    if not cryptography_available:
        raise RuntimeError("cryptography is not available")
    public_key = serialization.load_ssh_public_key(b(pubkey), backend=default_backend())
    pub_der = public_key.public_bytes(
        encoding=serialization.Encoding.DER,
        format=serialization.PublicFormat.SubjectPublicKeyInfo,
    )
    return _to_md5_fingerprint(pub_der)


def get_pubkey_comment(pubkey, default=None):
    if pubkey.startswith("ssh-"):
        # This is probably an OpenSSH key
        return pubkey.strip().split(" ", 3)[2]
    if default:
        return default
    raise ValueError("Public key is not in a supported format")
