# -*- coding: utf-8 -*-
# Copyright (c) 2017 CloudZero - ALL RIGHTS RESERVED - PROPRIETARY AND CONFIDENTIAL
# Unauthorized copying of this file and/or project, via any medium is strictly prohibited.
# Direct all questions to legal@cloudzero.com

"""
Contains functions for efficiently extracting parts of a CZREL.
CZRELs are used to unambiguously and uniquely identify explicit and derived relationships between resources and other
entities we extract from a cloud domain.
"""

from czid.czrel.validate import CZREL_CAPTURE_REGEX


def extract_all_components(czrel):
    """
    Extract and return all of the components of a CZREL as a tuple.

    Args:
        czrel (str): The CZREL to unpack

    Returns:
        3-tuple of strings - the components of the provider CZREL: subject, predicate, object.

    >>> extract_all_components('czrel>czrn:aws:lambda:us-west-2:123456789012:function:my-function>invoked-by>czrn:aws:lambda:us-west-2:123456789012:function:my-other-function')
    ('czrn:aws:lambda:us-west-2:123456789012:function:my-function', 'invoked-by', 'czrn:aws:lambda:us-west-2:123456789012:function:my-other-function')

    >>> extract_all_components('foobar')
    Traceback (most recent call last):
    ...
    ValueError: CZREL foobar is not valid
    """
    czrel_match = CZREL_CAPTURE_REGEX.fullmatch(czrel) if czrel else None
    if not czrel_match:
        raise ValueError(f'CZREL {czrel} is not valid')
    subject = czrel_match.group(1)
    predicate = czrel_match.group(7)
    object = czrel_match.group(8)
    return subject, predicate, object


def extract_subject(czrel):
    """
    Extract and return subject from a CZREL

    Args:
        czrel (str): The CZREL to unpack

    Returns:
        str - The subject

    >>> extract_subject('czrel>czrn:aws:lambda:us-west-2:123456789012:function:my-function>invoked-by>czrn:aws:lambda:us-west-2:123456789012:function:my-other-function')
    'czrn:aws:lambda:us-west-2:123456789012:function:my-function'

    >>> extract_subject('foobar')
    Traceback (most recent call last):
    ...
    ValueError: CZREL foobar is not valid
    """
    subject, _, _ = extract_all_components(czrel)
    return subject


def extract_object(czrel):
    """
    Extract and return object from a CZREL

    Args:
        czrel (str): The CZREL to unpack

    Returns:
        str - The object

    >>> extract_object('czrel>czrn:aws:lambda:us-west-2:123456789012:function:my-function>invoked-by>czrn:aws:lambda:us-west-2:123456789012:function:my-other-function')
    'czrn:aws:lambda:us-west-2:123456789012:function:my-other-function'

    >>> extract_object('foobar')
    Traceback (most recent call last):
    ...
    ValueError: CZREL foobar is not valid
    """
    _, _, object = extract_all_components(czrel)
    return object


def extract_predicate(czrel):
    """
    Extract and return predicate from a CZREL

    Args:
        czrel (str): The CZREL to unpack

    Returns:
        str - The predicate

    >>> extract_predicate('czrel>czrn:aws:lambda:us-west-2:123456789012:function:my-function>invoked-by>czrn:aws:lambda:us-west-2:123456789012:function:my-other-function')
    'invoked-by'

    >>> extract_predicate('foobar')
    Traceback (most recent call last):
    ...
    ValueError: CZREL foobar is not valid
    """
    _, predicate, _ = extract_all_components(czrel)
    return predicate
