import isArray from 'lodash/isArray'
import uniq from 'lodash/uniq'
import vRead from 'vinyl-read'
import { mixinPropertyUtils } from 'skypager-util/lib/properties'
import vFile from 'vfile'
import { DefaultPatterns } from '../document'

const { defineProperty } = Object

export const DefaultOptions = {
  patterns: DefaultPatterns,
}

export const toVFile = (vinyl, cwd) => {
  const options = {
    path: vinyl.path,
    contents: vinyl.contents,
    cwd: cwd || vinyl.cwd,
  }
  
  return new vFile(options)
}

export class DocumentImporter {
  static patterns = DefaultPatterns;

  static create (cwd, options = {}) {
    if (typeof options === 'string') {
      options = {
        patterns: [options],
        cwd
      }
    }

    if (isArray(options)) {
      options = {
        cwd,
        patterns: options,
      }
    }

    const importer = new DocumentImporter(cwd, {
      cwd,
      ...options
    })

    return importer
  }

  constructor (cwd, options = {}) {
    mixinPropertyUtils(this)

    if (typeof cwd !== 'string') {
      throw('Document Importers must be created with a cwd path')
    }

    this.cwd = cwd

    this.hide('options', {
      ...DefaultOptions,
      ...options,
    })

    delete this.options.cwd;

    this.patterns = [
      ...this.options.patterns || DefaultOptions.patterns || [],
      '!**/*.lock',
    ]

    if (this.options.collection) {
      this.patterns.push(...this.options.collection.patterns || [])
    }

    this.patterns = uniq(this.patterns)

    let status = 'CREATED'

    defineProperty(this, 'status', {
      configurable: false,
      get: () => status,
      set: ((newValue) => status = newValue)
    })

  }

  get fileWrappersSync() {
    return vRead.sync(this.patterns, {
      base: this.cwd,
      cwd: this.cwd,
      read: this.options.includeContents === true,
      ...this.options
    })
  }

  get fileWrappers() {
    return vRead(this.patterns, {
      base: this.cwd,
      cwd: this.cwd,
      read: this.options.includeContents === true,
      ...this.options
    })
  }

  readFilesSync (includeContents) {
    return vRead.sync(this.patterns, {
      base: this.cwd,
      cwd: this.cwd,
      read: includeContents !== false && this.options.includeContents === true,
      ...this.options
    })
  }

  readFiles (includeContents = false) {
    return vRead(this.patterns, {
      base: this.cwd,
      cwd: this.cwd,
      read: includeContents === true,
      ...this.options
    })
  }
}

export default DocumentImporter
