import {AnyJson, ApiResponse, HydraMetadata} from '~/types/data'
import UrlUtils from '~/services/utils/urlUtils'
import {METADATA_TYPE} from '~/types/enum/data'

/**
 * Normalisation et dé-normalisation ddu format de données Hydra
 */
class HydraDenormalizer {

  /**
   * Parse une réponse Hydra et retourne un objet ApiResponse
   *
   * @param {AnyJson} data
   * @return {AnyJson} réponse parsée
   */
  public static denormalize(data: AnyJson): ApiResponse {
    return {
      data: HydraDenormalizer.getData(data),
      metadata: HydraDenormalizer.getMetadata(data)
    }
  }

  protected static getData(hydraData: AnyJson): AnyJson {
    return hydraData['@type'] === 'hydra:Collection' ? hydraData['hydra:member'] : hydraData
  }

  /**
   * Génère les métadonnées d'un item ou d'une collection
   *
   * @param data
   * @protected
   */
  protected static getMetadata(data: AnyJson): HydraMetadata {
    if (data['@type'] !== 'hydra:Collection') {
      // A single item, no metadata
      return { type: METADATA_TYPE.ITEM }
    }

    const metadata: HydraMetadata = {
      totalItems: data['hydra:totalItems']
    }

    if (data['hydra:view']) {
      /**
       * Extract the page number from the IRIs in the hydra:view section
       */
      const extractPageNumber = (pos: string, default_: number | undefined=undefined): number | undefined => {
        const iri = data['hydra:view']['hydra:' + pos]
        if (!iri) {
          return default_
        }
        return UrlUtils.getParameter(
            data['hydra:view']['hydra:' + pos],
            'page',
            default_
        ) as number | undefined
      }

      // TODO: utile d'ajouter la page en cours?
      metadata.firstPage = extractPageNumber('first', 1)
      metadata.lastPage = extractPageNumber('last', 1)
      metadata.nextPage = extractPageNumber('next')
      metadata.previousPage = extractPageNumber('previous')
    }

    metadata.type = METADATA_TYPE.COLLECTION

    return metadata
  }
}

export default HydraDenormalizer
