text: import base64
  import json
  import os
  import pycountry
  from http import HTTPStatus
  from pathlib import Path
  
  import requests
  from flask import current_app, jsonify
  from flask_restx import Resource, cors
  
  from namex.models import Request, State
  from namex.utils.api_resource import handle_exception
  from namex.utils.auth import cors_preflight
  from namex.utils.logging import setup_logging
  from .api_namespace import api
  from namex.services.name_request.utils import get_mapped_entity_and_action_code
  
  setup_logging()  # Important to do this first
  
  
  @cors_preflight('GET')
  @api.route('/<int:nr_id>/result', strict_slashes=False, methods=['GET', 'OPTIONS'])
  @api.doc(params={
      'nr_id': 'NR ID - This field is required'
  })
  class ReportResource(Resource):
      @cors.crossdomain(origin='*')
      def get(self, nr_id):
          try:
              nr_model = Request.query.get(nr_id)
              if not nr_model:
                  return jsonify(message='{nr_id} not found'.format(nr_id=nr_model.id)), HTTPStatus.NOT_FOUND
  
              if nr_model.stateCd not in [State.APPROVED, State.CONDITIONAL, State.EXPIRED, State.REJECTED]:
                  return jsonify(message='Invalid NR state'.format(nr_id=nr_model.id)), HTTPStatus.BAD_REQUEST
  
              authenticated, token = ReportResource._get_service_client_token()
              if not authenticated:
                  return jsonify(message='Error in authentication'.format(nr_id=nr_model.id)),\
                         HTTPStatus.INTERNAL_SERVER_ERROR
  
              headers = {
                  'Authorization': 'Bearer {}'.format(token),
                  'Content-Type': 'application/json'
              }
              data = {
                  'reportName': ReportResource._get_report_filename(nr_model),
                  'template': "'" + base64.b64encode(bytes(self._get_template(), 'utf-8')).decode() + "'",
                  'templateVars': ReportResource._get_template_data(nr_model)
              }
              response = requests.post(url=current_app.config.get('REPORT_SVC_URL'), headers=headers,
                                       data=json.dumps(data))
  
              if response.status_code != HTTPStatus.OK:
                  return jsonify(message=str(response.content)), response.status_code
              return response.content, response.status_code
          except Exception as err:
              return handle_exception(err, 'Error retrieving the report.', 500)
  
      @staticmethod
      def _get_report_filename(nr_model):
          return 'NR {}.pdf'.format(nr_model.nrNum).replace(' ', '_')
  
      @staticmethod
      def _get_template():
          try:
              template_path = current_app.config.get('REPORT_TEMPLATE_PATH')
              template_code = Path(f'{template_path}/{ReportResource._get_template_filename()}').read_text()
              template_code = ReportResource._substitute_template_parts(template_code)
          except Exception as err:
              current_app.logger.error(err)
              raise err
          return template_code
  
      @staticmethod
      def _get_template_filename():
          return 'nameRequest.html'
  
      @staticmethod
      def _substitute_template_parts(template_code):
          template_path = current_app.config.get('REPORT_TEMPLATE_PATH')
          template_parts = [
              'name-request/style',
              'name-request/logo',
              'name-request/nrDetails',
              'name-request/nameChoices',
              'name-request/applicantContactInfo',
              'name-request/manageNameRequest',
              'name-request/resultDetails'
          ]
          # substitute template parts - marked up by [[filename]]
          for template_part in template_parts:
              template_part_code = Path(f'{template_path}/template-parts/{template_part}.html').read_text()
              template_code = template_code.replace('[[{}.html]]'.format(template_part), template_part_code)
  
          return template_code
  
      @staticmethod
      def _get_template_data(nr_model):
          if nr_model.requestTypeCd and (not nr_model.entity_type_cd or not nr_model.request_action_cd):
              # For the NRO ones.
              entity_type, request_action = get_mapped_entity_and_action_code(nr_model.requestTypeCd)
              nr_model.entity_type_cd = entity_type
              nr_model.request_action_cd = request_action
          nr_report_json = nr_model.json()
          nr_report_json['entityTypeDescription'] = ReportResource._get_entity_type_description(nr_model.entity_type_cd)
          isXPRO = nr_model.entity_type_cd in ['XCR', 'XUL', 'RLC', 'XLP', 'XLL', 'XCP', 'XSO']
          nr_report_json['isXPRO'] = isXPRO
          nr_report_json['requestCodeDescription'] = \
              ReportResource._get_request_action_cd_description(nr_report_json['request_action_cd'])
          nr_report_json['nrStateDescription'] = \
              ReportResource._get_state_cd_description(nr_report_json['stateCd'])
          if isXPRO and nr_report_json['nrStateDescription'] == 'Rejected':
              nr_report_json['nrStateDescription'] = 'Not Approved'
          if nr_report_json['expirationDate']:
              nr_report_json['expirationDate'] = nr_model.expirationDate.strftime('%B %-d, %Y')
          if nr_report_json['submittedDate']:
              nr_report_json['submittedDate'] = nr_model.submittedDate.strftime('%B %-d, %Y')
          if nr_report_json['applicants']['countryTypeCd']:
              nr_report_json['applicants']['countryName'] = \
                  pycountry.countries.search_fuzzy(nr_report_json['applicants']['countryTypeCd'])[0].name
          actions_obj = ReportResource._get_next_action_text(nr_model.entity_type_cd)
          if actions_obj:
              action_text = actions_obj.get(nr_report_json['request_action_cd'])
              if not action_text:
                  action_text = actions_obj.get('DEFAULT')
              if action_text:
                  nr_report_json['nextAction'] = action_text
          return nr_report_json
  
      @staticmethod
      def _get_service_client_token():
          auth_url = os.getenv('PAYMENT_SVC_AUTH_URL')
          client_id = os.getenv('PAYMENT_SVC_AUTH_CLIENT_ID')
          secret = os.getenv('PAYMENT_SVC_CLIENT_SECRET')
          auth = requests.post(
              auth_url,
              auth=(client_id, secret),
              headers={
                  'Content-Type': 'application/x-www-form-urlencoded'
              },
              data={
                  'grant_type': 'client_credentials',
                  'client_id': client_id,
                  'client_secret': secret
              }
          )
          if auth.status_code != 200:
              return False, auth.json()
  
          token = dict(auth.json())['access_token']
          return True, token
  
      @staticmethod
      def _get_request_action_cd_description(request_cd: str):
          request_cd_description = {
              'NEW': 'New Business',
              'MVE': 'Continuation in',
              'REH': 'Restoration or Reinstatement',
              'AML': 'Amalgamation',
              'NRO-NEWAML': 'Amalgamation',
              'CHG': 'Name Change',
              'CNV': 'Alteration',
              'NRO-REST': 'Restoration or Reinstatement'
          }
  
          return request_cd_description.get(request_cd, None)
  
      @staticmethod
      def _get_state_cd_description(state_cd: str):
          nr_state_description = {
              'APPROVED': 'Approved',
              'CONDITIONAL': 'Conditional Approval',
              'REJECTED': 'Rejected',
              'EXPIRED': 'Expired'
          }
  
          return nr_state_description.get(state_cd, None)
  
      @staticmethod
      def _get_entity_type_description(entity_type_cd: str):
          entity_type_descriptions = {
              # BC Types
              'CR': 'BC Limited Company',
              'UL': 'BC Unlimited Liability Company',
              'FR': 'BC Sole Proprietorship',
              'GP': 'BC General Partnership',
              'DBA': 'BC Doing Business As',
              'LP': 'BC Limited Partnership',
              'LL': 'BC Limited Liability Partnership',
              'CP': 'BC Cooperative Association',
              'BC': 'BC Benefit Company',
              'CC': 'BC Community Contribution Company',
              'SO': 'BC Social Enterprise',
              'PA': 'BC Private Act',
              'FI': 'BC Credit Union',
              'PAR': 'BC Parish',
              # XPRO and Foreign Types
              'XCR': 'Extraprovincial Limited Company',
              'XUL': 'Extraprovincial Unlimited Liability Company',
              'RLC': 'Extraprovincial Limited Liability Company',
              'XLP': 'Extraprovincial Limited Partnership',
              'XLL': 'Extraprovincial Limited Liability Partnership',
              'XCP': 'Extraprovincial Cooperative Association',
              'XSO': 'Extraprovincial Social Enterprise',
              # Used for mapping back to legacy oracle codes, description not required
              'FIRM': 'FIRM (Legacy Oracle)'
          }
          return entity_type_descriptions.get(entity_type_cd, None)
  
      @staticmethod
      def _get_next_action_text(entity_type_cd: str):
          next_action_text = {
              # BC Types
              'CR':  {
                 'DEFAULT': 'To complete your filing, visit <a href="corporateonline.gov.bc.ca">'
                            'corporateonline.gov.bc.ca</a> for more information'
              },
              'UL': {
                 'DEFAULT': 'To complete your filing, visit <a href="corporateonline.gov.bc.ca">'
                            'corporateonline.gov.bc.ca</a> for more information'
              },
              'FR': {
                 'NEW': 'To complete your filing, visit <a href="https://www2.gov.bc.ca/gov/content/employment-business/'
                        'business/managing-a-business/permits-licences/businesses-incorporated-companies/'
                        'proprietorships-partnerships/registering">Registering Proprietorships and Partnerships'
                        '</a> for more information',
                 'DEFAULT': 'To complete your filing, visit <a href="https://www2.gov.bc.ca/gov/content/'
                            'employment-business/business/managing-a-business/permits-licences/'
                            'businesses-incorporated-companies/proprietorships-partnerships/registering">'
                            'Registering Proprietorships and Partnerships</a> for more information. To learn more, visit '
                            '<a href="https://www2.gov.bc.ca/gov/content/employment-business/business/'
                            'managing-a-business/permits-licences/businesses-incorporated-companies/'
                            'proprietorships-partnerships/making-changes">Making Changes to your Proprietorship or'
                            ' Partnership</a>'
              },
              'GP': {
                 'NEW': 'To complete your filing, visit <a href="https://www2.gov.bc.ca/gov/content/employment-business/'
                        'business/managing-a-business/permits-licences/businesses-incorporated-companies/'
                        'proprietorships-partnerships/registering">Registering Proprietorships and Partnerships'
                        '</a> for more information',
                 'DEFAULT': 'To complete your filing, visit <a href="https://www2.gov.bc.ca/gov/content/'
                            'employment-business/business/managing-a-business/permits-licences/'
                            'businesses-incorporated-companies/proprietorships-partnerships/registering">'
                            'Registering Proprietorships and Partnerships</a> for more information. To learn more, visit '
                            '<a href="https://www2.gov.bc.ca/gov/content/employment-business/business/'
                            'managing-a-business/permits-licences/businesses-incorporated-companies/'
                            'proprietorships-partnerships/making-changes">Making Changes to your Proprietorship or'
                            ' Partnership</a>'
              },
              'DBA': {
                 'NEW': 'To complete your filing, visit <a href="https://www2.gov.bc.ca/gov/content/employment-business/'
                        'business/managing-a-business/permits-licences/businesses-incorporated-companies/'
                        'proprietorships-partnerships/registering">Registering Proprietorships and Partnerships'
                        '</a> for more information',
                 'DEFAULT': 'To complete your filing, visit <a href="https://www2.gov.bc.ca/gov/content/'
                            'employment-business/business/managing-a-business/permits-licences/'
                            'businesses-incorporated-companies/proprietorships-partnerships/registering">'
                            'Registering Proprietorships and Partnerships</a> for more information. To learn more, visit '
                            '<a href="https://www2.gov.bc.ca/gov/content/employment-business/business/'
                            'managing-a-business/permits-licences/businesses-incorporated-companies/'
                            'proprietorships-partnerships/making-changes">Making Changes to your Proprietorship or'
                            ' Partnership</a>'
              },
              'LP': {
                 'DEFAULT': 'To complete your filing, <a href= "https://www2.gov.bc.ca/gov/content/'
                            'employment-business/business/managing-a-business/permits-licences/'
                            'businesses-incorporated-companies/forms-corporate-registry">visit our Forms page</a> to'
                            ' download and submit a form'
              },
              'LL': {
                 'DEFAULT': 'To complete your filing, <a href= "https://www2.gov.bc.ca/gov/content/'
                            'employment-business/business/managing-a-business/permits-licences/'
                            'businesses-incorporated-companies/forms-corporate-registry">visit our Forms page</a> to'
                            ' download and submit a form'
              },
              'CP': 'BC Cooperative Association',
              'BC': {
                 'DEFAULT': 'To complete your filing, visit <a href="bcregistry.ca/business">www.bcregistry.gov.bc.ca</a>'
                            ' for more information'
              },
              'CC': {
                 'DEFAULT': 'To complete your filing, visit <a href="corporateonline.gov.bc.ca">'
                            'corporateonline.gov.bc.ca</a> for more information'
              },
              'SO': 'BC Social Enterprise',
              'PA': {
                 'DEFAULT': 'Submit appropriate form to BC Registries. Call if assistance required.'
              },
              'FI': {
                 'DEFAULT': 'Submit appropriate form to BC Registries. Call if assistance required.'
              },
              'PAR': {
                 'DEFAULT': 'Submit appropriate form to BC Registries. Call if assistance required.'
              },
              # XPRO and Foreign Types
              'XCR': {
                 'NEW': 'To complete your filing, visit <a href="corporateonline.gov.bc.ca">'
                        'corporateonline.gov.bc.ca</a> for more information',
                 'CHG': 'To complete your filing, visit <a href="corporateonline.gov.bc.ca">'
                        'corporateonline.gov.bc.ca</a> for more information',
                 'DEFAULT': 'To complete your filing, <a href= "https://www2.gov.bc.ca/gov/content/'
                            'employment-business/business/managing-a-business/permits-licences/'
                            'businesses-incorporated-companies/forms-corporate-registry">visit our Forms page</a> to'
                            ' download and submit a form'
              },
              'XUL': {
                 'DEFAULT': 'To complete your filing, visit <a href="corporateonline.gov.bc.ca">'
                            'corporateonline.gov.bc.ca</a> for more information'
              },
              'RLC': {
                  'DEFAULT': 'To complete your filing, visit <a href="corporateonline.gov.bc.ca">'
                            'corporateonline.gov.bc.ca</a> for more information'
              },
              'XLP': {
                 'DEFAULT': 'To complete your filing, <a href= "https://www2.gov.bc.ca/gov/content/'
                            'employment-business/business/managing-a-business/permits-licences/'
                            'businesses-incorporated-companies/forms-corporate-registry">visit our Forms page</a> to'
                            ' download and submit a form'
              },
              'XLL': {
                 'DEFAULT': 'To complete your filing, <a href= "https://www2.gov.bc.ca/gov/content/'
                            'employment-business/business/managing-a-business/permits-licences/'
                            'businesses-incorporated-companies/forms-corporate-registry">visit our Forms page</a> to'
                            ' download and submit a form'
              },
              'XCP': 'Extraprovincial Cooperative Association',
              'XSO': 'Extraprovincial Social Enterprise',
              # Used for mapping back to legacy oracle codes, description not required
              'FIRM': 'FIRM (Legacy Oracle)'
          }
          return next_action_text.get(entity_type_cd, None)
  
  
  
  
  
  
  
  
  