{{#models}}
{{#model}}
{{>partial_header}}

#' {{classname}} Class
#'
{{#vars}}
#' @field {{baseName}} {{title}}
{{/vars}}
#'
#' @importFrom R6 R6Class
#' @importFrom jsonlite fromJSON toJSON
#' @export
{{classname}} <- R6::R6Class(
  '{{classname}}',
  public = list(
    {{#vars}}
    `{{{baseName}}}` = NULL,
    {{/vars}}
    initialize = function({{#vars}}`{{baseName}}`{{#hasMore}}, {{/hasMore}}{{/vars}}){
      {{#vars}}
      if (!missing(`{{baseName}}`)) {
        {{^isListContainer}}
            {{#isInteger}}
                stopifnot(is.numeric(`{{baseName}}`), length(`{{baseName}}`) == 1)
            {{/isInteger}}
            {{#isLong}}
                stopifnot(is.numeric(`{{baseName}}`), length(`{{baseName}}`) == 1)
            {{/isLong}}
            {{#isFloat}}
                stopifnot(is.numeric(`{{baseName}}`), length(`{{baseName}}`) == 1)
            {{/isFloat}}
            {{#isDouble}}
                stopifnot(is.numeric(`{{baseName}}`), length(`{{baseName}}`) == 1)
            {{/isDouble}}
            {{#isString}}
                stopifnot(is.character(`{{baseName}}`), length(`{{baseName}}`) == 1)
            {{/isString}}
            {{#isDate}}
                stopifnot(is.character(`{{baseName}}`), length(`{{baseName}}`) == 1)
            {{/isDate}}
            {{#isDateTime}}
                stopifnot(is.character(`{{baseName}}`), length(`{{baseName}}`) == 1)
            {{/isDateTime}}
            {{^isPrimitiveType}}
                stopifnot(R6::is.R6(`{{baseName}}`))
            {{/isPrimitiveType}}
        {{/isListContainer}}
        {{#isListContainer}}
            {{#isPrimitiveType}}
                stopifnot(is.vector(`{{baseName}}`), length(`{{baseName}}`) != 0)
                sapply(`{{baseName}}`, function(x) stopifnot(is.character(x)))
            {{/isPrimitiveType}}
            {{^isPrimitiveType}}
                stopifnot(is.vector(`{{baseName}}`), length(`{{baseName}}`) != 0)
                sapply(`{{baseName}}`, function(x) stopifnot(R6::is.R6(x)))
            {{/isPrimitiveType}}
        {{/isListContainer}}
        self$`{{baseName}}` <- `{{baseName}}`
      }
      {{/vars}}
    },
    toJSON = function() {
      {{classname}}Object <- list()
      {{#vars}}
      if (!is.null(self$`{{baseName}}`)) {
        {{classname}}Object[['{{baseName}}']] <-
        {{#isListContainer}}
            {{#isPrimitiveType}}
                self$`{{baseName}}`
            {{/isPrimitiveType}}
            {{^isPrimitiveType}}
                sapply(self$`{{baseName}}`, function(x) x$toJSON())
            {{/isPrimitiveType}}
        {{/isListContainer}}
        {{^isListContainer}}
            {{#isPrimitiveType}}
                self$`{{baseName}}`
            {{/isPrimitiveType}}
            {{^isPrimitiveType}}
                self$`{{baseName}}`$toJSON()
            {{/isPrimitiveType}}
        {{/isListContainer}}
      }
      {{/vars}}

      {{classname}}Object
    },
    fromJSON = function({{classname}}Json) {
      {{classname}}Object <- jsonlite::fromJSON({{classname}}Json)
      {{#vars}}
      if (!is.null({{classname}}Object$`{{baseName}}`)) {
        {{#isListContainer}}
            {{#isPrimitiveType}}
                self$`{{baseName}}` <- {{classname}}Object$`{{baseName}}`
            {{/isPrimitiveType}}
            {{^isPrimitiveType}}
                self$`{{baseName}}` <- sapply({{classname}}Object$`{{baseName}}`, function(x) {
                  {{baseName}}Object <- {{dataType}}$new()
                  {{baseName}}Object$fromJSON(jsonlite::toJSON(x, auto_unbox = TRUE))
                  {{baseName}}Object
            })
            {{/isPrimitiveType}}
        {{/isListContainer}}
        {{^isListContainer}}
            {{#isPrimitiveType}}
                self$`{{baseName}}` <- {{classname}}Object$`{{baseName}}`
            {{/isPrimitiveType}}
            {{^isPrimitiveType}}
                {{baseName}}Object <- {{dataType}}$new()
                {{baseName}}Object$fromJSON(jsonlite::toJSON({{classname}}Object${{baseName}}, auto_unbox = TRUE))
                self$`{{baseName}}` <- {{baseName}}Object
            {{/isPrimitiveType}}
        {{/isListContainer}}
      }
      {{/vars}}
    },
    toJSONString = function() {
       outstring <- sprintf(
        '{
           {{#vars}}
           "{{baseName}}":
              {{#isListContainer}}
                 {{#isPrimitiveType}}
                      {{#isNumeric}}[%d]{{/isNumeric}}
                      {{^isNumeric}}["%s"]{{/isNumeric}}
                  {{/isPrimitiveType}}
                  {{^isPrimitiveType}}["%s"]{{/isPrimitiveType}}
              {{/isListContainer}}
              {{^isListContainer}}
                  {{#isPrimitiveType}}
                      {{#isNumeric}}%d{{/isNumeric}}
                      {{^isNumeric}}"%s"{{/isNumeric}}
                  {{/isPrimitiveType}}
                  {{^isPrimitiveType}}"%s"{{/isPrimitiveType}}
              {{/isListContainer}}
              {{#hasMore}},{{/hasMore}}
           {{/vars}}
        }',
        {{#vars}}
        {{#isListContainer}}
            {{#isPrimitiveType}}
                paste0(self$`{{baseName}}`, collapse='","'){{#hasMore}},{{/hasMore}}
            {{/isPrimitiveType}}
            {{^isPrimitiveType}}
                paste0(sapply(self$`{{baseName}}`, function(x) x$toJSON()), collapse='","'){{#hasMore}},{{/hasMore}}
            {{/isPrimitiveType}}
        {{/isListContainer}}
        {{^isListContainer}}
            {{#isPrimitiveType}}
                self$`{{baseName}}`{{#hasMore}},{{/hasMore}}
            {{/isPrimitiveType}}
            {{^isPrimitiveType}}
                self$`{{baseName}}`$toJSON(){{#hasMore}},{{/hasMore}}
            {{/isPrimitiveType}}
        {{/isListContainer}}
        {{/vars}}
      )
      gsub("[\r\n]| ", "", outstring)
    },
    fromJSONString = function({{classname}}Json) {
      {{classname}}Object <- jsonlite::fromJSON({{classname}}Json)
      {{#vars}}
      {{#isListContainer}}
          {{#isPrimitiveType}}
              self$`{{baseName}}` <- {{classname}}Object$`{{baseName}}`
          {{/isPrimitiveType}}
          {{^isPrimitiveType}}
              self$`{{baseName}}` <- sapply({{classname}}Object$`{{baseName}}`, function(x) {{dataType}}$new()$fromJSON(jsonlite::toJSON(x, auto_unbox = TRUE)))
          {{/isPrimitiveType}}
      {{/isListContainer}}
      {{^isListContainer}}
          {{#isPrimitiveType}}
              self$`{{baseName}}` <- {{classname}}Object$`{{baseName}}`
          {{/isPrimitiveType}}
          {{^isPrimitiveType}}
              {{dataType}}Object <- {{dataType}}$new()
              self$`{{baseName}}` <- {{dataType}}Object$fromJSON(jsonlite::toJSON({{classname}}Object${{baseName}}, auto_unbox = TRUE))
          {{/isPrimitiveType}}
      {{/isListContainer}}
      {{/vars}}
    }
  )
)
{{/model}}
{{/models}}
