require 'docker_cloud'
require 'capistrano/docker-cloud/helpers/collection_helper'

module Capistrano
  module DockerCloud
    class RecordNotFound < Exception; end

    class Base
      include Capistrano::DockerCloud::Helpers::CollectionHelper

      # ~~~~ Class Methods ~~~~
      def self.subclass_name
        # FIXME : Find a better way to archive this.
        ancestors.first.to_s.split('::').last.downcase + 's'
      end

      def self.find(uuid)
        object = resource.get(uuid)
        return object if object
        raise Capistrano::DockerCloud::RecordNotFound
      rescue RestClient::ResourceNotFound => error
        puts "ERROR: #{error.response}"
      end

      def self.find_by(options = {})
        case
        when options.key?(:name)
          new(find_by_name(options[:name]))
        else
          raise "You can only search #{subclass_name} by `:name`."
        end
      end

      def self.find_by_name(name)
        resource.all.detect do |stack|
          stack.name.downcase == name
        end
      end

      def self.resource
        connection.send("#{subclass_name}")
      end

      def self.configure(username, api_key)
        @@dockercloud_username = username
        @@dockercloud_api_key = api_key
      end

      def self.connection
        @@connection ||= ::DockerCloud::Client.new(@@dockercloud_username,
                                                   @@dockercloud_api_key)
      end

      #
      # Rails like belongs_to association
      #
      def self.belongs_to(name)
        define_method("#{name.to_s}=") do |object|
          instance_variable_set("@#{name.to_s}", object)
        end
        define_method("#{name.to_s}") { instance_variable_get("@#{name.to_s}") }
      end

      def self.redeploy(uuid)
        resource.redeploy(uuid)
      end

      # ~~~~ Instance Methods ~~~~
      def connection
        self.class.connection
      end

      def reload!
        initialize(self.class.find(uuid))
      end

      def redeploy
        self.class.redeploy(uuid)
      end
    end
  end
end
