<graphql.version>5.10.0</graphql.version>
		<kotlin.version>1.3.10</kotlin.version>

		<dependency>
		    <groupId>com.graphql-java-kickstart</groupId>
		    <artifactId>graphql-spring-boot-starter</artifactId>
		    <version>${graphql.version}</version>
		</dependency>
		<!-- to embed GraphiQL tool -->
		<dependency>
		    <groupId>com.graphql-java-kickstart</groupId>
		    <artifactId>graphiql-spring-boot-starter</artifactId>
		    <version>${graphql.version}</version>
		    <scope>runtime</scope>
		</dependency>
		<!-- to embed Altair tool -->
		<dependency>
		    <groupId>com.graphql-java-kickstart</groupId>
		    <artifactId>altair-spring-boot-starter</artifactId>
		    <version>${graphql.version}</version>
		    <scope>runtime</scope>
		</dependency>
		<dependency>
		    <groupId>com.graphql-java-kickstart</groupId>
		    <artifactId>playground-spring-boot-starter</artifactId>
		    <version>${graphql.version}</version>
		    <scope>runtime</scope>
		</dependency>

graphql:
  servlet:
    mapping: /graphql
    enabled: true

type Film {
    id: ID!
    titre: String
    titreFr: String
    duree: Int
    annee: Int
    synopsis: String
    type: FilmType
    voteMoyenne: Float
    voteNombre: Int
    imdbId: String
    votes: [Vote]
    personnages: [Personnage]
    studio: Studio
    realisateurs: [Personne]
    scenaristes: [Personne]
}

type Personnage {
    id: ID!
    nom: String!
    hero: Boolean
    film: Film!
    acteurs: [Personne!]!
}

type Personne {
    id: ID!
    nom: String!
    anneeNaissance: Int
    anneeDeces: Int
    imdbId: String
    personnages: [Personnage]
    filmRealises: [Film]
    filmScenarises: [Film]
}

type Query {

	filmById(id: ID!): Film

	filmsByTitreFr(titreFr: String!): [Film]

}

@Component
public class QueryResolver implements GraphQLQueryResolver {

	@Autowired
	private FilmRepository filmRepository;

	public Optional<Film> filmById(Long id) {
		return filmRepository.findById(id);
	}

	public List<Film> filmsByTitreFr(String titreFr) {
		return filmRepository.findByTitreFr(titreFr);
	}

}

{
  filmById(id: 1518508) {
    titre
  }
}

{
  "data": {
    "filmById": {
      "titre": "Angel Has Fallen"
    }
  }
}

{
  filmById(id: 1518508) {
    titre
    titreFr
    annee
    personnages {
      nom
    }
  }
}

@Component
public class FilmResolver implements GraphQLResolver<Film> {
	@Autowired
	private PersonnageRepository personnageRepository;

	public Set<Personnage> personnages(Film film) {
		return personnageRepository.findByFilmId(film.getId());
	}
}

{
  "data": {
    "filmById": {
      "titre": "Angel Has Fallen",
      "titreFr": "La chute du président",
      "annee": 2019,
      "personnages": [
        {
          "nom": "Allan Trumbull"
        },
        {
          "nom": "Mike Banning"
        }
      ]
    }
  }
}

{
  filmsByTitreFr(titreFr: "Alice au pays des merveilles") {
    id
    titre
    annee
    personnages {
      nom
      acteurs {
        nom
        personnages {
          nom
          film {
            titre
            titreFr
            annee
          }
        }
      }
    }
  }
}

select distinct f1
from Film f1
left join fetch f1.personnages p1
left join fetch p1.acteurs a
left join fetch a.personnages p2
left join fetch p2.film f2
where
f1.titreFr = :titreFr

CALL graphql.idl('
type Film {
    id: Long!
    titre: String
    titreFr: String
    duree: Int
    annee: Int
    synopsis: String
    type: String
    voteMoyenne: Float
    voteNombre: Int
    imdbId: String
    votes:        [Vote]       @relation(name:"NOTE",direction:IN)
    studio:       Studio       @relation(name:"PRODUIT",direction:IN)
    personnages:  [Personnage] @relation(name:"FIGURE_DANS",direction:IN)
    realisateurs: [Personne]   @relation(name:"REALISE",    direction:IN)
    scenaristes:  [Personne]   @relation(name:"SCENARISE",  direction:IN)
}

type Personnage {
    id: Long!
    nom: String!
    hero: Boolean
    film: Film!           @relation(name:"FIGURE_DANS")
    acteurs: [Personne!]! @relation(name:"INTERPRETE",  direction:IN)
}

type Personne {
    id: Long!
    nom: String!
    anneeNaissance: Int
    anneeDeces: Int
    imdbId: String
    personnages: [Personnage] @relation(name:"INTERPRETE")
    filmRealises: [Film]      @relation(name:"REALISE")
    filmScenarises: [Film]    @relation(name:"SCENARISE")
}

type Studio {
    id: Long!
    nom: String!
    films: [Film] @relation(name:"PRODUIT")
}

type Vote {
    id: Long!
    note: Int!
    critique: String
    film: Film! @relation(name:"NOTE")
}
')

MATCH (`film`:`Film`)
WHERE `film`.`titreFr` = "Alice au pays des merveilles"
RETURN graphql.labels(`film`) AS `_labels`,
`film`.`id` AS `id`,
`film`.`titre` AS `titre`,
`film`.`annee` AS `annee`,
[ (`film`)<-[:`FIGURE_DANS`]-(`film_personnages`:`Personnage`)  
	| `film_personnages` {`_labels` : graphql.labels(`film_personnages`), .`nom`, `acteurs` : [ 
	(`film_personnages`)<-[:`INTERPRETE`]-(`film_personnages_acteurs`:`Personne`)  
	| `film_personnages_acteurs` {`_labels` : graphql.labels(`film_personnages_acteurs`), .`nom`, `personnages` : [ 
		(`film_personnages_acteurs`)-[:`INTERPRETE`]->(`film_personnages_acteurs_personnages`:`Personnage`)  
		| `film_personnages_acteurs_personnages` {`_labels` : graphql.labels(`film_personnages_acteurs_personnages`), .`nom`, `film` : head([ 
			(`film_personnages_acteurs_personnages`)-[:`FIGURE_DANS`]->(`film_personnages_acteurs_personnages_film`:`Film`)  
			| `film_personnages_acteurs_personnages_film` {`_labels` : graphql.labels(`film_personnages_acteurs_personnages_film`), .`titre`, .`titreFr`, .`annee`}
			])}
		]}
	]}
] AS `personnages`