import rubberduck from 'rubberduck/dist/rubberduck'
import setupServiceModule from './service-module/service-module'
import setupAuthModule from './auth-module/auth-module'
import setupFeathersModule from './feathers-module/feathers-module'
import deepAssign from 'deep-assign'
import clone from 'clone'
import { normalizePath, makeConfig } from './utils'

const defaultOptions = {
  idField: 'id',
  auto: true,
  autoForce: false,
  // Determines the source of the module name. 'short', 'path', or 'explicit'
  nameStyle: 'short',
  feathers: {
    name: 'feathers'
  },
  auth: {
    name: 'auth',
    userService: null,
    state: {},
    getters: {},
    mutations: {},
    actions: {}
  }
}

export default function (clientOrStore, options = {}, modules = {}) {
  options = deepAssign({}, clone(defaultOptions), options)

  return function feathersVuex (arg) {
    const asFeathersPlugin = !arg
    const asVuePlugin = !asFeathersPlugin
    const feathers = asFeathersPlugin ? this : clientOrStore
    const store = asFeathersPlugin ? clientOrStore : arg

    if (asFeathersPlugin && !store) {
      throw new Error('You must pass the vuex store to the Feathers-Vuex plugin.')
    } else if (asVuePlugin && !feathers) {
      throw new Error('You must pass a Feathers Client instance to the Feathers-Vuex plugin.')
    }

    // Normalize the modules into objects if they were provided as a string.
    Object.keys(modules).forEach(name => {
      if (typeof modules[name] === 'string') {
        modules[name] = { name: modules[name] }
      }
    })

    const addToFeathersModule = setupFeathersModule(store, options)(feathers)
    const setup = setupServiceModule(store)
    const addConfigTo = makeConfig(options, modules)
    setupAuthModule(store, options)(feathers)

    // Add .vuex() function to each service to allow individual configuration.
    const addVuexMethod = function (service, options, modules) {
      service.vuex = function (moduleOptions = {}) {
        // Setting force will rebuild the vuex store.
        const force = moduleOptions.hasOwnProperty('force') ? moduleOptions.force : true
        delete moduleOptions.force

        normalizePath(service)
        addConfigTo(service, moduleOptions)
        setup(service, { force })
        addToFeathersModule(service)
        return service
      }
    }

    // Duck punch the service method so we can detect when services are created.
    const emitter = rubberduck.emitter(feathers).punch('service')
    emitter.on('afterService', function (service, args, instance) {
      addVuexMethod(service, options, modules)

      // Only auto-setup on service creation, not on lookup
      if (options.auto && !service.vuexOptions) {
        service.vuex({force: false})
      }
      return service
    })

    // If running as a Vue Plugin, setup each service that was previously created.
    asVuePlugin && Object.keys(feathers.services).forEach(location => feathers.service(location))
  }
}

@@ -615,12 +615,10 @@
 ce: 
-null
+''
 ,%0A  
@@ -765,32 +765,22 @@
 %7B%0A  
-options
+var theClone
  =
- deepAssign(%7B%7D,
  clo
@@ -797,16 +797,48 @@
 Options)
+%0A  options = deepAssign(theClone
 , option

Use empty string for default userService