<commit_before>package me.apidoc.swagger

import translators.Resolver
import lib.{ServiceConfiguration, Text, UrlKey}
import java.io.File
import scala.collection.JavaConversions._
import play.api.libs.json.{Json, JsArray, JsObject, JsString, JsValue}

import io.swagger.parser.SwaggerParser
import com.wordnik.swagger.models.{ComposedModel, ModelImpl, RefModel, Swagger}
import com.wordnik.swagger.models.{parameters => swaggerparams}
import com.gilt.apidoc.spec.v0.models._
import com.wordnik.swagger.models.properties.Property

import lib.Text
import com.gilt.apidoc.spec.v0.models._
import scala.annotation.tailrec

case class Parser(config: ServiceConfiguration) {

  def parseString(
    contents: String
  ): Service = {
    parse(Util.writeToTempFile(contents))
  }

  def parse(
    path: File
  ): Service = {
    val swagger = new SwaggerParser().read(path.toString)
    val info = swagger.getInfo()
    val applicationKey = UrlKey.generate(info.getTitle())
    val specModels = models(swagger)
    val resolver = Resolver(models = specModels)

    Service(
      name = info.getTitle(),
      description = Option(info.getDescription()),
      baseUrl = translators.BaseUrl(Util.toArray(swagger.getSchemes).map(_.toString), swagger.getHost, Option(swagger.getBasePath)).headOption,
      namespace = config.applicationNamespace(applicationKey),
      organization = Organization(key = config.orgKey),
      application = Application(key = applicationKey),
      version = config.version,
      enums = Nil,
      unions = Nil,
      models = specModels,
      imports = Nil,
      headers = Nil,
      resources = translators.Resource.mergeAll(resources(swagger, resolver))
    )
  }

  private def models(swagger: Swagger): Seq[Model] = {
    buildModels(
      selector = ModelSelector(Util.toMap(swagger.getDefinitions)),
      resolver = Resolver(models = Nil)
    )
  }

  @tailrec
  private def buildModels(
    selector: ModelSelector,
    resolver: Resolver
  ): Seq[Model] = {
    selector.next() match {
      case None => {
        selector.remaining.toList match {
          case Nil => resolver.models
          case remaining => sys.error("Failed to resolve definitions: " + selector.remaining.map(_.name).mkString(", "))
        }
      }

      case Some(mydefinition) => {
        val name = mydefinition.name
        val newModel = mydefinition.definition match {
          case m: ComposedModel => {
            var composedModel: Option[Model] = None

            m.getInterfaces.foreach { i =>
              sys.error(s"TODO: Handle interfaces for definition[$name]: $i")
            }

            m.getAllOf.foreach { swaggerModel =>
              val thisModel = swaggerModel match {
                case rm: RefModel => resolver.resolveWithError(rm)
                case m: ModelImpl => translators.Model(resolver, name, m)
                case _ => sys.error(s"Unsupported composition model[$name] - $swaggerModel")
              }

              composedModel = composedModel match {
                case None => Some(
                  thisModel.copy(
                    name = name,
                    plural = Text.pluralize(name)
                  )
                )
                case Some(cm) => Some(translators.Model.compose(cm, thisModel))
              }
            }<commit_msg>Cleanup imports<commit_after>package me.apidoc.swagger

import translators.Resolver
import lib.{ServiceConfiguration, Text, UrlKey}

import io.swagger.parser.SwaggerParser
import com.wordnik.swagger.models.{ComposedModel, ModelImpl, RefModel, Swagger}
import java.io.File

import scala.collection.JavaConversions._
import com.gilt.apidoc.spec.v0.models._
import scala.annotation.tailrec

case class Parser(config: ServiceConfiguration) {

  def parseString(
    contents: String
  ): Service = {
    parse(Util.writeToTempFile(contents))
  }

  def parse(
    path: File
  ): Service = {
    val swagger = new SwaggerParser().read(path.toString)
    val info = swagger.getInfo()
    val applicationKey = UrlKey.generate(info.getTitle())
    val specModels = models(swagger)
    val resolver = Resolver(models = specModels)

    Service(
      name = info.getTitle(),
      description = Option(info.getDescription()),
      baseUrl = translators.BaseUrl(Util.toArray(swagger.getSchemes).map(_.toString), swagger.getHost, Option(swagger.getBasePath)).headOption,
      namespace = config.applicationNamespace(applicationKey),
      organization = Organization(key = config.orgKey),
      application = Application(key = applicationKey),
      version = config.version,
      enums = Nil,
      unions = Nil,
      models = specModels,
      imports = Nil,
      headers = Nil,
      resources = translators.Resource.mergeAll(resources(swagger, resolver))
    )
  }

  private def models(swagger: Swagger): Seq[Model] = {
    buildModels(
      selector = ModelSelector(Util.toMap(swagger.getDefinitions)),
      resolver = Resolver(models = Nil)
    )
  }

  @tailrec
  private def buildModels(
    selector: ModelSelector,
    resolver: Resolver
  ): Seq[Model] = {
    selector.next() match {
      case None => {
        selector.remaining.toList match {
          case Nil => resolver.models
          case remaining => sys.error("Failed to resolve definitions: " + selector.remaining.map(_.name).mkString(", "))
        }
      }

      case Some(mydefinition) => {
        val name = mydefinition.name
        val newModel = mydefinition.definition match {
          case m: ComposedModel => {
            var composedModel: Option[Model] = None

            m.getInterfaces.foreach { i =>
              sys.error(s"TODO: Handle interfaces for definition[$name]: $i")
            }

            m.getAllOf.foreach { swaggerModel =>
              val thisModel = swaggerModel match {
                case m: RefModel => resolver.resolveWithError(m)
                case m: ModelImpl => translators.Model(resolver, name, m)
                case _ => sys.error(s"Unsupported composition model[$name] - $swaggerModel")
              }

              composedModel = composedModel match {
                case None => Some(
                  thisModel.copy(
                    name = name,
                    plural = Text.pluralize(name)
                  )
                )
                case Some(cm) => Some(translators.Model.compose(cm, thisModel))
              }
            }
{'fraction_non_alphanumeric': 0.10465659554586514, 'fraction_numerical': 0.0004672169444011836, 'mean_word_length': 2.482646420824295, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 28, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '822659', 'n_tokens_mistral': 1842, 'n_tokens_neox': 1790, 'n_words': 382}