class Stuff
  def for_any_user options = nil, &block
    yield if Labels.state_check Labels.extract(options), current_user
  end

  def not_for_any_user options = nil, &block
    return if Labels.state_check Labels.extract(options), current_user
    yield 
  end

  def is? role
    role == :guest
  end
  
  def current_user
    Stuff.new
  end   
  
  private

  module Labels    
    class << self
      def extract options
        case options
        when Symbol
          return :logged_in if logged_in_labels.include?(options)
          return :logged_out if logged_out_labels.include?(options)
        when Hash
          return :logged_in if logged_in_labels.any? {|lab| options[lab] }
          return :logged_out if logged_out_labels.any? {|lab| options[lab] }    
        end    
        raise ArgumentException, "Unknown option #{options}"
      end

      def state_check state, current_user
        logged_in_check(state, current_user) || logged_out_check(state, current_user)
      end

      def logged_in_check state, current_user
        state == :logged_in && is_not_guest?(current_user)
      end

      def logged_out_check state, current_user
        state == :logged_out && is_guest?(current_user)
      end
      
      def is_not_guest? current_user
        !current_user || (current_user && !current_user.is?(:guest))
      end

      def is_guest? current_user
        current_user && current_user.is?(:guest)
      end

      def logged_in_labels
        [:logged_in, :signed_in, :not_logged_out, :not_signed_out]
      end

      def logged_out_labels
        [:logged_out, :signed_out, :not_logged_in, :not_signed_in]
      end  
    end
  end
end  

s = Stuff.new

s.for_any_user :logged_in do
  puts "log out - for_any_user :logged_in"
end

s.for_any_user :logged_out do
  puts "log in - for_any_user :logged_out"
end

s.for_any_user :not_logged_in do
  puts "log in - for_any_user :not_logged_in"
end

s.for_any_user :not_logged_out do
  puts "log out - for_any_user :not_logged_out"
end

s.not_for_any_user :logged_in do
  puts "log in - not_for_any_user :logged_in"
end

s.not_for_any_user :logged_out do
  puts "log out - not_for_any_user :logged_out"
end

s.not_for_any_user :not_logged_in do
  puts "log out - not_for_any_user :not_logged_in"
end

s.not_for_any_user :not_logged_out do
  puts "log in - not_for_any_user :not_logged_out"
end
