/**
 * Some part of codes are borrowed/modified from vue-loader
 * https://github.com/vuejs/vue-loader
 * Released under the MIT License
 */

const loaderUtils = require('loader-utils')
const compile = require('./modules/template-compiler')
const genId = require('./modules/gen-id')

module.exports = function (content) {
  this.cacheable()
  const isServer = this.options.target === 'node'
  const id = `data-v-${genId(this.resourcePath)}`

  // Acquire the query of target file
  const { style: stylePath } = loaderUtils.parseQuery('?' + this.request.split('?').pop())
  const { scoped } = loaderUtils.parseQuery(this.query)

  const compiled = compile(content, this.options)
  compiled.errors.forEach(error => {
    this.emitError('template syntax error ' + error)
  })

  const shouldHotReload = !isServer &&
    !this.minimize &&
    process.env.NODE_ENV !== 'production'

  let output = writeRenderCode(compiled.code, id, stylePath, scoped)
  if (shouldHotReload) {
    output += writeHotReloadCode(id)
  }

  return output
}

function writeRenderCode (compiled, id, stylePath, isScoped) {
  return [
    writeInjectStyle(stylePath, isScoped, id),
    compiled,
    'module.exports = function (_exports) {',
    '  var options = _exports',
    '  if (typeof _exports === "function") options = _exports.options',
    writeInjectScopedId(stylePath && isScoped, id),
    writeInjectCssModules(stylePath),
    '  options.render = render',
    '  options.staticRenderFns = staticRenderFns',
    '  if (module.hot && api) {',
    `    api.createRecord("${id}", options)`,
    '  }',
    '  return _exports',
    '}\n'
  ].join('\n')
}

function writeInjectStyle (stylePath, isScoped, id) {
  if (!stylePath) return ''

  if (!isScoped) {
    return `var styles = require('${stylePath}')`
  }

  const loaderPath = require.resolve('./scoped-style-loader.js')
  return `var styles = require('${loaderPath}?id=${id}!${stylePath}')`
}

function writeInjectScopedId (isScoped, id) {
  return isScoped
    ? `  options._scopeId = '${id}'`
    : ''
}

function writeInjectCssModules (isEnabled) {
  if (!isEnabled) return ''

  return [
    '  if (Object.keys(styles).length > 0) {',
    '    if (!options.computed) options.computed = {}',
    '    options.computed.$style = function () { return styles }',
    '  }'
  ].join('\n')
}

function writeHotReloadCode (id) {
  return [
    'var api = null',
    'if (module.hot) {(function () {',
    '  api = require("vue-hot-reload-api")',
    '  api.install(require("vue"))',
    '  if (!api.compatible) return',
    '  module.hot.accept()',
    '  if (module.hot.data) {',
    `    api.rerender("${id}", { render: render, staticRenderFns: staticRenderFns })`,
    '  }',
    '})()}\n'
  ].join('\n')
}

@@ -576,18 +576,15 @@
 nst 
-%7B scoped %7D
+options
  = l
@@ -659,23 +659,21 @@
 t, this.
-options
+query
 )%0A  comp
@@ -927,16 +927,24 @@
 lePath, 
+options.
 scoped)%0A

Fix option passing