text: """
  Provides all Warnings checkers for sam template
  """
  import logging
  
  LOG = logging.getLogger(__name__)
  
  
  class TemplateWarning:
      """
      Top level class which all warnings should extend from.
      """
  
      def check(self, template_dict):
          raise Exception("NotImplementedException")
  
  
  def _get_deployment_preferences_status(function):
      """
      Takes a AWS::Serverless::Function resource and checks if resource have a deployment preferences applied
      to it. If DeploymentPreference found then it returns its status if it is enabled or not.
      """
      deployment_preference = function.get("Properties", {}).get("DeploymentPreference", None)
      if not deployment_preference:
          # Missing deployment preferences treated as not enabled.
          return False
      return deployment_preference.get("Enabled", True)  # enabled by default
  
  
  class TemplateWarningsChecker:
      def __init__(self):
          self.all_warnings = {
              CodeDeployWarning.__name__: CodeDeployWarning(),
              CodeDeployConditionWarning.__name__: CodeDeployConditionWarning(),
          }
  
      def check_template_for_warning(self, warning_name, template_dict):
          """
          Checks provided template against the warning based on warning_name.
          Parameters
          ----------
          warning_name: Name of warning which needs to be checked.
          template_dict: template dict
  
          Returns
          -------
          warning_message if warning detected. None if no warning found.
          """
          if not template_dict:
              return None
          warning = self.all_warnings.get(warning_name, None)
          if not warning:
              LOG.error("UnknownWarning name found: %s", warning_name)
              return None
  
          should_warn, warning_message = warning.check(template_dict)
          if should_warn:
              return warning_message
          return None
  
  
  class CodeDeployWarning(TemplateWarning):
      WARNING_MESSAGE = """Your template includes a deployment configuration that will create an additional unecessary CodeDeploy Service Role.
  By 9/25 the SAM service will no longer create this extra role, and any applications deployed after this date that directly
  reference this role will produce an error as the role will be removed. For more information on this issue and how to
  mitigate it, please read these docs[1]
  
  [1] https://github.com/aws/aws-sam-cli/wiki/08-2020-codeploy-servicerole
      """
  
      def check(self, template_dict):
          """
          Checking if template dictionary have CodeDeployWarning or not.
          """
          functions = [
              resource
              for (_, resource) in template_dict.get("Resources", {}).items()
              if resource.get("Type", "") == "AWS::Serverless::Function"
          ]
          deployment_features_enabled_count = sum(
              1 for function in functions if _get_deployment_preferences_status(function)
          )
          deployment_features_disabled_count = sum(
              1 for function in functions if not _get_deployment_preferences_status(function)
          )
  
          send_warning = deployment_features_enabled_count > 0 and deployment_features_disabled_count > 0
          return (send_warning, self.WARNING_MESSAGE) if send_warning else (send_warning, "")
  
  
  class CodeDeployConditionWarning(TemplateWarning):
      WARNING_MESSAGE = """Your template includes a deployment configuration with a Condition attached to it. SAM currently has a bug that
  ignores conditions for DeploymentPreference, causing CodeDeploy DeploymentGroups to be created in error.
  After October 23, 2020 the SAM service will fix this bug, causing subsequent deployments to remove these CodeDeploy DeploymentGroups
  if the attached Condition is false. For more information on this issue and how to mitigate it, please read these docs[1]
  
  [1] https://github.com/aws/aws-sam-cli/wiki/08-2020-codeploy-deploymentgroup-condition
      """
  
      def check(self, template_dict):
          """
          Checking if template dictionary have Function with Condition and DeploymentPreferences which
          will trigger this warning.
          """
          functions = [
              resource
              for (_, resource) in template_dict.get("Resources", {}).items()
              if resource.get("Type", "") == "AWS::Serverless::Function"
          ]
          for function in functions:
              if self._have_condition(function) and self._have_deployment_preferences(function):
                  return (True, self.WARNING_MESSAGE)
          return (False, "")
  
      def _have_condition(self, function):
          condition = function.get("Condition", None)
          return condition is not None
  
      def _have_deployment_preferences(self, function):
          deployment_preference = function.get("Properties", {}).get("DeploymentPreference", None)
          return deployment_preference is not None
  