require 'dunlop/generators'
class Dunlop::ScenarioGenerator < Rails::Generators::NamedBase
  include Dunlop::Generators::GeneratorHelpers

  source_root File.expand_path('../templates', __FILE__)
  class_option :columns, type: :array, default: []
  class_option :workflow_steps, type: :array, default: []

  def setup_workflow_steps
    unless options.workflow_steps.any?
      say "you have not specified the workflow steps for the scenario. Define using\n  --workflow_steps=#{WorkflowInstance.possible_workflow_step_names.join(' ')}\nor\n  --workflow_steps=all"
      abort
    end

    wi_factory_code = "factory 'workflow_instance/#{file_name}', aliases: [:workflow_instance_#{file_name}], class: 'WorkflowInstance::#{class_name}', parent: :workflow_instance"
    inject_before_last_end "spec/factories/workflow_instance.rb", wi_factory_code

    wi_batch_factory_code = "factory 'workflow_instance_batch/#{file_name}', aliases: [:workflow_instance_batch_#{file_name}], class: 'WorkflowInstanceBatch::#{class_name}', parent: :workflow_instance_batch"
    inject_before_last_end "spec/factories/workflow_instance_batch.rb", wi_batch_factory_code

    workflow_steps.each do |ws|
      @workflow_step = ws
      template "workflow_step_model.rb.erb", "app/models/#{workflow_step}/#{file_name}.rb"
      template "workflow_step_collection.rb.erb", "app/models/#{workflow_step}/#{file_name}/collection.rb"

      template "workflow_step_controller.rb.erb", "app/controllers/#{workflow_step}/#{file_name.pluralize}_controller.rb"

      wi_step_factory_code = "factory '#{workflow_step}/#{file_name}', aliases: [:#{workflow_step}_#{file_name}], class: '#{workflow_step.classify}::#{class_name}', parent: :#{workflow_step}"
      inject_before_last_end "spec/factories/#{workflow_step}.rb", wi_step_factory_code
    end

    if behavior == :revoke and (WorkflowInstance.possible_workflow_step_names - workflow_step.map(&:to_sym)).any?
      say "There are still workflow steps associated with the scenario, so the base models (and controllers) will remain", :blue
      abort
    end
  end

  def workflow_step
    @workflow_step
  end

  def workflow_steps
    return @workflow_steps if @workflow_steps
    all_possible = WorkflowInstance.possible_workflow_step_names.map(&:to_s)
    selection = options.workflow_steps.select(&:present?)
    abort "Not all specified workflow steps are actually present" unless selection.all?{|step_name| all_possible.include? step_name}
    @workflow_steps = options.workflow_steps == ['all'] ? all_possible : selection
  end

  def create_controllers
    template "workflow_instance_controller.rb.erb", "app/controllers/workflow_instance/#{file_name.pluralize}_controller.rb"
    template "workflow_instance_batch_controller.rb.erb", "app/controllers/workflow_instance_batch/#{file_name.pluralize}_controller.rb"
  end

  def create_migration
    return unless options.columns.any?
    extra_columns = options.columns.select{|column_spec| WorkflowInstance.column_names.exclude?(column_spec.split(':').first) }
    return unless extra_columns.any?
    say "rails generate migration add_columns_to_workflow_instances #{extra_columns.join(' ')}" if behavior == :invoke
  end

  def create_model_and_collection
    template "model.rb.erb", "app/models/workflow_instance/#{file_name}.rb"
    template "collection.rb.erb", "app/models/workflow_instance/#{file_name}/collection.rb"
    template "batch_model.rb.erb", "app/models/workflow_instance_batch/#{file_name}.rb"
  end

  def create_views
    template "translations.yml.erb", "config/locales/scenario-#{file_name}.yml"
  end

  def setup_spec_support
  end

  def setup_scenario_on_base
    return if behavior == :invoke and WorkflowInstance.scenario_names.map(&:to_s).include?(file_name)
    add_to_symbol_list "app/models/workflow_instance.rb", 'setup_scenarios', file_name
  end
end
