<commit_before>package uk.ac.wellcome.display.models

import io.circe.Json
import io.circe.parser._
import org.scalatest.Suite
import uk.ac.wellcome.models._

trait DisplayJacksonModuleTestBase {this: Suite =>

  def items(its: List[IdentifiedItem]) =
    its
      .map { it =>
        s"""{
          "id": "${it.canonicalId}",
          "type": "${it.ontologyType}",
          "locations": [
            ${locations(it.locations)}
          ]
        }"""
      }
      .mkString(",")

  def locations(locations: List[Location]) =
    locations
      .map { location(_) }
      .mkString(",")

  def location(loc: Location) = loc match {
    case l: DigitalLocation => digitalLocation(l)
    case l: PhysicalLocation => physicalLocation(l)
  }

  def digitalLocation(loc: DigitalLocation) =
    s"""{
      "type": "${loc.ontologyType}",
      "locationType": "${loc.locationType}",
      "url": "${loc.url}",
      "license": ${license(loc.license)}
    }"""

  def physicalLocation(loc: PhysicalLocation) =
    s"""
       {
        "type": "${loc.ontologyType}",
        "locationType": "${loc.locationType}",
        "label": "${loc.label}"
       }
     """

  def license(license: License) =
    s"""{
      "label": "${license.label}",
      "licenseType": "${license.licenseType}",
      "type": "${license.ontologyType}",
      "url": "${license.url}"
    }"""

  def identifier(identifier: SourceIdentifier) =
    s"""{
      "type": "Identifier",
      "identifierScheme": "${identifier.identifierScheme}",
      "value": "${identifier.value}"
    }"""

  def identifiedOrUnidentifiable[T](displayableAgent: Displayable[T],
                                    f: T => String) =
    displayableAgent match {
      case Unidentifiable(ag) => f(ag)
      case Identified(ag, id, identifiers) =>
        val agent = parse(f(ag)).right.get.asObject.get
        val identifiersJson = identifiers.map { sourceIdentifier =>
          parse(identifier(sourceIdentifier)).right.get
        }
        val newJson = ("id", Json.fromString(id)) +: (
          "identifiers",
          Json.arr(identifiersJson: _*)) +: agent
        Json.fromJsonObject(newJson).spaces2
    }

  def abstractAgent(ag: AbstractAgent) =
    ag match {
      case a: Agent => agent(a)
      case o: Organisation => organisation(o)
      case p: Person => person(p)
    }

  def person(p: Person) = {
    s"""{
        "type": "Person",
        ${optionalString("prefix", p.prefix)},
        ${optionalString("numeration", p.numeration)},
        "label": "${p.label}"
      }"""
  }<commit_msg>Add a comment explaining the purpose of identifiedOrUnidentifiable<commit_after>package uk.ac.wellcome.display.models

import io.circe.Json
import io.circe.parser._
import org.scalatest.Suite
import uk.ac.wellcome.models._

trait DisplayJacksonModuleTestBase {this: Suite =>

  def items(its: List[IdentifiedItem]) =
    its
      .map { it =>
        s"""{
          "id": "${it.canonicalId}",
          "type": "${it.ontologyType}",
          "locations": [
            ${locations(it.locations)}
          ]
        }"""
      }
      .mkString(",")

  def locations(locations: List[Location]) =
    locations
      .map { location(_) }
      .mkString(",")

  def location(loc: Location) = loc match {
    case l: DigitalLocation => digitalLocation(l)
    case l: PhysicalLocation => physicalLocation(l)
  }

  def digitalLocation(loc: DigitalLocation) =
    s"""{
      "type": "${loc.ontologyType}",
      "locationType": "${loc.locationType}",
      "url": "${loc.url}",
      "license": ${license(loc.license)}
    }"""

  def physicalLocation(loc: PhysicalLocation) =
    s"""
       {
        "type": "${loc.ontologyType}",
        "locationType": "${loc.locationType}",
        "label": "${loc.label}"
       }
     """

  def license(license: License) =
    s"""{
      "label": "${license.label}",
      "licenseType": "${license.licenseType}",
      "type": "${license.ontologyType}",
      "url": "${license.url}"
    }"""

  def identifier(identifier: SourceIdentifier) =
    s"""{
      "type": "Identifier",
      "identifierScheme": "${identifier.identifierScheme}",
      "value": "${identifier.value}"
    }"""

  // Some of our fields can be optionally identified (e.g. creators).
  //
  // Values in these fields are wrapped in either "Unidentifiable" or
  // "Identified".  In the first case, we use the default serialisation
  // unmodified.  In the second case, we modify the JSON to include
  // the "id" field and the "identifiers" field.
  //
  def identifiedOrUnidentifiable[T](displayableAgent: Displayable[T],
                                    f: T => String) =
    displayableAgent match {
      case Unidentifiable(ag) => f(ag)
      case Identified(ag, id, identifiers) =>
        val agent = parse(f(ag)).right.get.asObject.get
        val identifiersJson = identifiers.map { sourceIdentifier =>
          parse(identifier(sourceIdentifier)).right.get
        }
        val newJson = ("id", Json.fromString(id)) +: (
          "identifiers",
          Json.arr(identifiersJson: _*)) +: agent
        Json.fromJsonObject(newJson).spaces2
    }

  def abstractAgent(ag: AbstractAgent) =
    ag match {
      case a: Agent => agent(a)
      case o: Organisation => organisation(o)
      case p: Person => person(p)
    }

  def person(p: Person) = {
    s"""{
        "type": "Person",
        ${optionalString("prefix", p.prefix)},
        ${optionalString("numeration", p.numeration)},
        "label": "${p.label}"
      }"""
  }
{'fraction_non_alphanumeric': 0.16275712739083364, 'fraction_numerical': 0.00036088054853843375, 'mean_word_length': 2.54185303514377, 'pattern_counts': {'":': 38, '<': 3, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '988467', 'n_tokens_mistral': 1661, 'n_tokens_neox': 1618, 'n_words': 359}