require 'db/mongo/models/stack_template/stack_template_factory'
require 'app/api3/parsers/stack_template'
require_relative "request_handler"
require 'exceptions/conflict_exception'

module Devops
  module API3
    module Handler
      class StackTemplate < RequestHandler

        set_parser Devops::API3::Parser::StackTemplateParser

        def stack_templates
          # we just need to build json from attributes hash, so there is no need
          # to build appropriate (not Base) class
          Model::StackTemplateBase.all
        end

        def stack_templates_for_provider provider
          Model::StackTemplateBase.where(provider: provider)
        end

        def create_stack_template provider
          template_model = Model::StackTemplateFactory.create(provider, parser.create)
          template_model.owner = parser.current_user
          template_model.save
          template_model
        end

        def get_stack_template id
          Model::StackTemplateBase.find(id)
        end

        def delete_stack_template id
          envs_with_this_template = envs_using_stack_template(id)

          if envs_with_this_template.empty?
            Devops::Model::StackTemplateBase.find(id).delete
          else
            raise Exception::ConflictError.new("Stack template '#{id}' is already in use in #{envs_with_this_template.map{|project, envs| "#{project}: #{envs.join(', ')}"}.join('; ')}")
          end
        end

        private

        # returns:
        # { "project" => ["environment"] }
        def envs_using_stack_template(stack_template_id)
          Devops::Model::Project.all.inject({}) do |usages, project|
            envs_with_this_template = project.environments.select do |env|
              stack_categories = env.categories.select {|t| t.provider.type == Model::CategoryProvider::STACK_TYPE}
              used_templates = stack_categories.map {|c| c.provider.stack_template}
              used_templates.include?(stack_template_id)
            end
            next usages if envs_with_this_template.empty?

            usages[project.id] = envs_with_this_template.map(&:id)
            usages
          end
        end

      end
    end
  end
end
