import {pick, omit} from 'lodash'
import assert from 'assert'
import {lazyGetter} from './utils'

const OVERRIDABLE_FIELDS = ['jsonType', 'type', 'name', 'title', 'description', 'options', 'fieldsets']

const ARRAY_CORE = {
  name: 'array',
  type: null,
  jsonType: 'array',
  of: []
}

export const ArrayType = {
  get() {
    return ARRAY_CORE
  },
  extend(subTypeDef, createMemberType) {
    const parsed = Object.assign(pick(ARRAY_CORE, OVERRIDABLE_FIELDS), subTypeDef, {
      type: ARRAY_CORE,
    })
    lazyGetter(parsed, 'of', () => {
      return subTypeDef.of.map(ofTypeDef => {
        return createMemberType(ofTypeDef)
      })
    })

    return subtype(parsed)

    function subtype(parent) {
      return {
        get() {
          return parent
        },
        extend: extensionDef => {
          if (extensionDef.of) {
            throw new Error('Cannot override `of` property of subtypes of "array"')
          }
          const current = Object.assign({}, parent, pick(extensionDef, OVERRIDABLE_FIELDS), {type: parent})
          return subtype(current)
        }
      }
    }
  }
}
const Person = ArrayType.extend({
  name: 'person',
  title: 'Person',
  of: [
    {type: 'string', name: 'lol'}
  ]
}, v => v)

const TypeOfPerson = Person.extend({
  name: 'typeofperson',
  title: 'Type Of Person'
}, v => v)

const TypeOfTypeOfPerson = TypeOfPerson.extend({
  name: 'typeoftypeofperson',
  title: 'Type Of Type Of Person'
}, v => v)

assert.equal(TypeOfTypeOfPerson.get().type, TypeOfPerson.get())
assert.equal(TypeOfTypeOfPerson.get().type, TypeOfPerson.get())
assert.equal(TypeOfTypeOfPerson.get().fields, Person.get().fields)
assert.throws(
  () => TypeOfTypeOfPerson.extend({name: 'lol', of: []}),
  /Cannot override `of` property of subtypes of "array"/
)
// console.log('TypeOfTypeOfPerson', TypeOfTypeOfPerson.get())

@@ -9,14 +9,8 @@
 pick
-, omit
 %7D fr
@@ -25,36 +25,8 @@
 sh'%0A
-import assert from 'assert'%0A
 impo
@@ -1075,747 +1075,4 @@
 %7D%0A%7D%0A
-const Person = ArrayType.extend(%7B%0A  name: 'person',%0A  title: 'Person',%0A  of: %5B%0A    %7Btype: 'string', name: 'lol'%7D%0A  %5D%0A%7D, v =%3E v)%0A%0Aconst TypeOfPerson = Person.extend(%7B%0A  name: 'typeofperson',%0A  title: 'Type Of Person'%0A%7D, v =%3E v)%0A%0Aconst TypeOfTypeOfPerson = TypeOfPerson.extend(%7B%0A  name: 'typeoftypeofperson',%0A  title: 'Type Of Type Of Person'%0A%7D, v =%3E v)%0A%0Aassert.equal(TypeOfTypeOfPerson.get().type, TypeOfPerson.get())%0Aassert.equal(TypeOfTypeOfPerson.get().type, TypeOfPerson.get())%0Aassert.equal(TypeOfTypeOfPerson.get().fields, Person.get().fields)%0Aassert.throws(%0A  () =%3E TypeOfTypeOfPerson.extend(%7Bname: 'lol', of: %5B%5D%7D),%0A  /Cannot override %60of%60 property of subtypes of %22array%22/%0A)%0A// console.log('TypeOfTypeOfPerson', TypeOfTypeOfPerson.get())%0A

Remove stray test code from array schema type