require 'time'
require 'pathname'

module Ec2ssh
  class SshConfig
    HEADER = "### EC2SSH BEGIN ###"
    FOOTER = "### EC2SSH END ###"

    attr_reader :path, :sections

    def initialize(path=nil)
      @path     = path || "#{ENV['HOME']}/.ssh/config"
      @sections = {}
    end

    def parse!
      return unless mark_exist?
      ec2_config = config_src.match(/#{HEADER}\n(.*)#{FOOTER}/m).to_s

      current_section = 'default'
      @sections[current_section] = Section.new('default')

      ec2_config.split(/\n+/).each do |line|
        if line =~ /#{Section::HEADER} (.+)/
          current_section = $1
          @sections[current_section] ||= Section.new(current_section)
        elsif line =~ /^#/ # ignore
        elsif line =~ /^$/ # ignore
        else
          @sections[current_section].append("#{line}\n")
        end
      end
    end

    def append_mark!
      replace! ""
      File.open(@path, "a") do |f|
        f.puts wrap("")
      end
    end

    def mark_exist?
      config_src =~ /#{HEADER}\n.*#{FOOTER}\n/m
    end

    def replace!(str)
      save! config_src.gsub(/#{HEADER}\n.*#{FOOTER}\n/m, str)
    end

    def config_src
      unless File.exist?(@path)
        File.open(@path, "w", 0600).close()
      end

      @config_src ||= File.open(@path, "r") do |f|
        f.read
      end
    end

    def save!(str)
      File.open(@path, "w") do |f|
        f.puts str
      end
    end

    def wrap(text)
      return <<-END
#{HEADER}
# Generated by ec2ssh http://github.com/mirakui/ec2ssh
# DO NOT edit this block!
# Updated #{Time.now.iso8601}
#{text}
#{FOOTER}
      END
    end

    class Section
      HEADER = "# section:"

      attr_accessor :name
      attr_reader   :text

      def initialize(name, text = '')
        @name = name
        @text = text
      end

      def append(text)
        @text << text
      end

      def replace!(text)
        @text = text
      end

      def to_s
        if text.empty?
          ""
        else
          <<-EOS
#{HEADER} #{@name}
#{@text}
          EOS
        end
      end
    end
  end
end
