text: # Copyright 2020 The StackStorm Authors.
  # Copyright 2019 Extreme Networks, Inc.
  #
  # 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.
  
  from __future__ import absolute_import
  
  import logging
  import os
  import yaml
  
  from st2client import commands
  from st2client.commands.resource import add_auth_token_to_kwargs_from_cli
  
  
  LOG = logging.getLogger(__name__)
  
  
  class WorkflowBranch(commands.Branch):
      def __init__(self, description, app, subparsers, parent_parser=None):
          super(WorkflowBranch, self).__init__(
              "workflow", description, app, subparsers, parent_parser=parent_parser
          )
  
          # Add subparser to register subcommands for managing workflows.
          help_message = "List of commands for managing workflows."
          self.subparsers = self.parser.add_subparsers(help=help_message)
  
          # Register workflow commands.
          self.commands["inspect"] = WorkflowInspectionCommand(self.app, self.subparsers)
  
  
  class WorkflowInspectionCommand(commands.Command):
      def __init__(self, *args, **kwargs):
          name = "inspect"
          description = (
              "Inspect workflow definition and return the list of errors if any."
          )
          args = tuple([name, description] + list(args))
          super(WorkflowInspectionCommand, self).__init__(*args, **kwargs)
  
          # Add argument options.
          arg_group = self.parser.add_mutually_exclusive_group()
  
          arg_group.add_argument(
              "--file", dest="file", help="Local file path to the workflow definition."
          )
  
          arg_group.add_argument(
              "--action",
              dest="action",
              help="Reference name for the registered action. This option works only if the file "
              "referenced by the entry point is installed locally under /opt/stackstorm/packs.",
          )
  
      @property
      def manager(self):
          return self.app.client.managers["Workflow"]
  
      def get_file_content(self, file_path):
          if not os.path.isfile(file_path):
              raise Exception('File "%s" does not exist on local system.' % file_path)
  
          with open(file_path, "r") as f:
              content = f.read()
  
          return content
  
      @add_auth_token_to_kwargs_from_cli
      def run(self, args, **kwargs):
          wf_def_file = args.file
  
          # If file path not provided, try the action reference. This only works if the command
          # is executed locally where the content is stored.
          if not wf_def_file:
              action_ref = args.action
              action_manager = self.app.client.managers["Action"]
              action = action_manager.get_by_ref_or_id(ref_or_id=action_ref)
  
              if not action:
                  raise Exception('Unable to identify action "%s".' % action_ref)
  
              wf_def_file = (
                  "/opt/stackstorm/packs/"
                  + action.pack
                  + "/actions/"
                  + action.entry_point
              )
  
          wf_def = self.get_file_content(wf_def_file)
  
          return self.manager.inspect(wf_def, **kwargs)
  
      @add_auth_token_to_kwargs_from_cli
      def run_and_print(self, args, **kwargs):
          errors = self.run(args, **kwargs)
  
          if not isinstance(errors, list):
              raise TypeError("The inspection result is not type of list: %s" % errors)
  
          if not errors:
              print("No errors found in workflow definition.")
              return
  
          print(yaml.safe_dump(errors, default_flow_style=False, allow_unicode=True))
  