ngClassify = require 'ng-classify'
coffee     = require 'coffee-script'
util       = require './util'

class Classifier
  constructor: (@grunt, @options) ->

  compile: (file = '') ->
    @lines = file.split('\n') or []

    @process()
    @compiled = ngClassify(@content, @callback() or @options)
    @postClassify()

    return @compiled

  process: () ->
    isOneLiner = /.*@classify\s*\(.*\).*/.test(@lines[0])

    if (isOneLiner)
      annotation = @lines.shift()
    else
      stopIndex = do => return i for line, i in @lines when /^class/.test(line.trim()) # returns first match
      annotation = @lines.splice(0, stopIndex).join('\n')

    @grunt.log.debug("@annotation: multiline => #{!isOneLiner}")
    @grunt.log.debug("@annotation: content => #{content}")

    eval(coffee.compile(annotation))

  classify: (def) ->
    @grunt.verbose.ok('@classify: ' + JSON.stringify(def || {}))
    @require(!!def.require, def.inject) if def.require
    @module(def.module) if def.module
    @prefix(def.prefix) if def.prefix

  postClassify: () ->
    @compiled = "#{@define}\n" + @compiled.split('\n').map(util.pad).join('\n') if @isRequire

  require: (isRequire, dependencies = []) ->
    dependencies.push('angular')
    quotedDependencies = dependencies.map((d) -> "'#{d}'").join(', ')
    dependencies       = dependencies.map((d) -> d.substring(d.lastIndexOf('/') + 1)).join(', ')

    @grunt.verbose.ok("@require: dependencies => #{dependencies}; quotedDependencies => #{quotedDependencies}")

    @isRequire = !!isRequire
    @define    = "define [#{quotedDependencies}], (#{dependencies}) ->"
    @content   = @lines.join '\n'

  module: (name = @options.appName) ->
    @grunt.verbose.ok("@module: name => #{name}")
    @options.appName = name

  prefix: (name = @options.prefix) ->
    @grunt.verbose.ok("@prefix: name => #{name}")
    @options.prefix = name

  callback: () ->
    return @options.callback(@path) if !!@options.callback and @options.callback instanceof Function
    return null

module.exports = Classifier