require 'memoist'
require 'stacker/differ'
require 'stacker/resolver'
require 'stacker/stack/component'

module Stacker
  class Stack
    class Parameters < Component

      extend Memoist

      def available
        @available ||= stack.region.defaults.fetch('Parameters', {}).merge(
          stack.options.fetch('Parameters', {})
        )
      end

      def required
        @required ||= stack.template.local.fetch 'Parameters', {}
      end

      def local
        @local ||= available.slice *required.keys
      end

      def missing
        @missing ||= required.keys - local.keys
      end

      def remote
        @remote ||= client.parameters
      end

      def resolved
        @resolved ||= resolver.resolved
      end

      def resolver
        @resolver ||= Resolver.new stack.region, local
      end

      def diff *args
        Differ.yaml_diff Hash[resolved.sort], Hash[remote.sort], *args
      end
      memoize :diff

    end
  end
end

require 'memoist'
require 'stacker/differ'
require 'stacker/resolver'
require 'stacker/stack/component'

module Stacker
  class Stack
    class Parameters < Component

      extend Memoist

      # everything required by the template
      def template_definitions
        stack.template.local.fetch 'Parameters', {}
      end

      def region_defaults
        stack.region.defaults.fetch 'parameters', {}
      end

      # template defaults merged with region and stack-specific overrides
      def local
        region_defaults = stack.region.defaults.fetch 'parameters', {}

        template_defaults = Hash[
          template_definitions.select { |_, opts|
            opts.key?('Default')
          }.map { |name, opts|
            [name, opts['Default']]
          }
        ]

        available = region_defaults.merge(
          template_defaults.merge(
            stack.options.fetch 'parameters', {}
          )
        )

        available.slice *template_definitions.keys
      end

      def missing
        template_definitions.keys - local.keys
      end

      def remote
        client.parameters
      end
      memoize :remote

      def resolved
        resolver.resolved
      end
      memoize :resolved

      def resolver
        Resolver.new stack.region, local
      end
      memoize :resolver

      def diff *args
        Differ.yaml_diff Hash[resolved.sort], Hash[remote.sort], *args
      end
      memoize :diff

    end
  end
end

Use template default values, when available
Use template default values, when available

AWS will set the defaults if we don't. Might as well. The diff will
now also accurately reflect what's being changed.

Signed-off-by: Evan Owen <a31932a4150a6c43f7c4879727da9a731c3d5877@gmail.com>
