"""
Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: MIT-0
"""
import json
import logging
from typing import Any, Dict, List, Tuple, Union
from cfnlint.conditions._utils import get_hash
LOGGER = logging.getLogger(__name__)
REF_REGION = get_hash({"Ref": "AWS::Region"})
class EqualParameter:
hash: str = ""
def __init__(self, value: dict):
self._value = value
self.hash: str = get_hash(value)
def __eq__(self, __o: Any):
return self.hash == __o.hash
class Equal:
hash: str
_left: Union[EqualParameter, str]
_right: Union[EqualParameter, str]
_is_static: Union[bool, None]
_is_region: Tuple[bool, str]
def __init__(self, equal: List[Union[str, dict]]) -> None:
self._is_static = None
if isinstance(equal, list) and len(equal) == 2:
# sort to keep consistancy from random ordering
# pylint: disable=unnecessary-lambda
equal_s = sorted(equal, key=lambda value: json.dumps(value))
self._left = self._init_parameter(equal_s[0])
self._right = self._init_parameter(equal_s[1])
self.hash = get_hash([self._left, self._right])
if isinstance(self._left, str) and isinstance(self._right, str):
self._is_static = self._left == self._right
elif isinstance(self._left, EqualParameter) and isinstance(
self._right, EqualParameter
):
self._is_static = self._left == self._right
self._is_region = (False, "")
if isinstance(self._left, EqualParameter):
if self._left.hash == REF_REGION and isinstance(self._right, str):
self._is_region = (True, self._right)
if isinstance(self._right, EqualParameter):
if self._right.hash == REF_REGION and isinstance(self._left, str):
self._is_region = (True, self._left)
return
raise ValueError("Equals has to be a list of two values")
def _init_parameter(
self, parameter: Union[Dict, str]
) -> Union[EqualParameter, str]:
if isinstance(parameter, dict):
return EqualParameter(parameter)
return str(parameter)
@property
def is_static(self) -> Union[bool, None]:
"""Returns a boolean value if the result is always True or False or None if
it isn't a static boolean
Args: None
Returns:
Union[bool, None]: None if the equals can be True or False or True/False if
the equals will always return the same result
"""
return self._is_static
@property
def parameters(self) -> List[EqualParameter]:
"""Returns a List of the EqualParameter that make up the Condition
Args: None
Returns:
List[Equal]: A list of the left and right equal parameters if they are
of type EqualParameter
"""
params = []
if isinstance(self._left, EqualParameter):
params.append(self._left)
if isinstance(self._right, EqualParameter):
params.append(self._right)
return params
@property
def is_region(self) -> Tuple[bool, str]:
"""Returns a Tuple if the condition is comparing a region to a string
Args: None
Returns:
Tuple[bool, str]: Tuple where the boolean is True if the condition
is using Ref: AWS::Region and the second element is for the region
being compared
"""
return self._is_region
@property
def left(self):
return self._left
@property
def right(self):
return self._right