text: # -*- coding: utf-8 -*-
  """ Covid coronavirus statistics based on John Hopkins University statistics
  
  """
  import requests
  
  from covid import config
  from covid.john_hopkins.models import CountryModel, CovidModel
  
  BASE_URL = "https://services1.arcgis.com"
  PATH = (
      "/0MSEUqKaxRlEPj5g/arcgis/rest/services/ncov_cases/FeatureServer/2/query"
  )
  URL = BASE_URL + PATH
  SOURCE = config.JOHN_HOPKINS
  
  
  class Covid:
      """Class handells all functionality"""
  
      def __init__(self):
          self.source = SOURCE
  
      @staticmethod
      def __get_total_cases_by_country_id(object_id: str) -> dict:
          """Method formats and encodes the URL for a specific country information regarding Covid
  
          Args:
              country (str): Country name e.g. "sweden"
  
          Returns:
              dict: Country related information regarding Coronavirus
              example:
                      {
                          'country': 'Sweden',
                          'confirmed': 355,
                          'active': 334,
                          'deaths': 0,
                          'recovered': 1,
                          'latitude': 63.0,
                          'longitude': 16.0,
                          'last_update': 1583893094000
                      }
          """
  
          params = dict(
              f="json",
              where=f"OBJECTID = {object_id}",
              returnGeometry="false",
              spatialRel="esriSpatialRelIntersects",
              outFields="*",
              resultOffset="0",
              resultRecordCount="1",
              cacheHint="true",
          )
  
          response = requests.get(URL, params=params).json()
          try:
              return response["features"][0]["attributes"]
          except KeyError:
              raise Exception(response)
  
      def __get_total_by_case(self, case: str) -> int:
          """Method fetchs the total value of a specific case (Deaths, Confirmed cases and Recovered cases)
  
          Args:
              case (str): cases = "Deaths", "Confirmed" and "Recovered"
  
          Returns:
              str: Total value
          """
          params = dict(
              f="json",
              where="Confirmed > 0",
              returnGeometry="false",
              spatialRel="esriSpatialRelIntersects",
              outFields="*",
              outStatistics=str(
                  [
                      {
                          "statisticType": "sum",
                          "onStatisticField": f"{case}",
                          "outStatisticFieldName": "value",
                      }
                  ]
              ),
              cacheHint="true",
          )
          response = requests.get(URL, params=params).json()
          try:
              return response["features"][0]["attributes"]["value"]
          except KeyError:
              raise Exception(response)
  
      def __get_all_cases(self) -> list:
          """Method fetches all data related to Covid
  
          Returns:
              list: list of Covid data
                  example:
                          [
                              {
                                  'id': '53',
                                  'country': 'China',
                                  'confirmed': 81020,
                                  'active': 9960,
                                  'deaths': 3217,
                                  'recovered': 67843,
                                  'latitude': 30.5928,
                                  'longitude': 114.3055,
                                  'last_update': 1584097775000
                              }
          """
          params = dict(
              f="json",
              where="Confirmed > 0",
              returnGeometry="false",
              spatialRel="esriSpatialRelIntersects",
              outFields="*",
              orderByFields="Confirmed desc",
              resultOffset="0",
              resultRecordCount="200",
              cacheHint="true",
          )
          response = requests.get(URL, params=params).json()
          try:
              return response["features"]
          except KeyError:
              raise Exception(response)
  
      def get_data(self) -> list:
          """Method fetches all data related to Covid"""
  
          cases = self.__get_all_cases()
          return [CovidModel(**case["attributes"]).dict() for case in cases]
  
      def get_total_deaths(self) -> int:
          """Method fetches and returns total deaths number
  
          Returns:
              int: Total number of deaths at this time
          """
          return self.__get_total_by_case("Deaths")
  
      def get_total_confirmed_cases(self) -> int:
          """Method fetches and returns the total number of confirmed cases
  
          Returns:
              int: Total number of confirmed cases at this time
          """
          return self.__get_total_by_case("Confirmed")
  
      def list_countries(self) -> list:
          """Method returns the names of all countries available, so that it can be used when
          querying status by a specific country
  
          Returns:
              list[str]: list of country names
          """
          cases = self.__get_all_cases()
          return [CountryModel(**case["attributes"]).dict() for case in cases]
  
      def get_status_by_country_id(self, country_id) -> dict:
          """Method fetches and returns specific country information related to coronavirus
  
          Args:
              country (str):  Country name e.g. "sweden"
  
          Returns:
              dict: Country related information regarding Coronavirus
              example:
                      {
                          'country': 'Sweden',
                          'confirmed': 355,
                          'active': 334,
                          'deaths': 0,
                          'recovered': 1,
                          'latitude': 63.0,
                          'longitude': 16.0,
                          'last_update': 1583893094000
                      }
          """
  
          case = self.__get_total_cases_by_country_id(country_id)
          return CovidModel(**case).dict()
  
      def get_status_by_country_name(self, country_name) -> dict:
          """Method fetches and returns specific country information related to coronavirus
  
          Args:
              country (str):  Country name e.g. "sweden"
  
          Returns:
              dict: Country related information regarding Coronavirus
              example:
                      {
                          'country': 'Sweden',
                          'confirmed': 355,
                          'active': 334,
                          'deaths': 0,
                          'recovered': 1,
                          'latitude': 63.0,
                          'longitude': 16.0,
                          'last_update': 1583893094000
                      }
          """
  
          country = filter(
              lambda country: country["name"].lower() == country_name.lower(),
              self.list_countries(),
          )
          try:
              country = next(country)
          except StopIteration:
              raise ValueError(
                  f"There is no country called '{country_name}', to check available country names use `list_countries()`"
              )
          case = self.__get_total_cases_by_country_id(country["id"])
          return CovidModel(**case).dict()
  