class Doc
  attr_reader :id, :title, :layout, :content, :content_list, :updated_at, :timestamp, :cache_key

  def self.all
    Dir.entries(Rails.root.join("docs")).select { |doc| doc.match(/\.[md|html]/i) }
  end

  def self.all_files
    all.map do |doc|
      file = IO.read(Rails.root.join("docs/#{doc}"))

      if File.extname(doc) == ".html"
        title = "Style Guide"
      elsif (md = file.match(/^(?<metadata>---\s*\n.*?\n?)^(---\s*$)/m))
        metadata = YAML.load(md[:metadata])
        title = metadata["title"]
      end

      { id: File.basename(doc, ".*"),
        title: title,
        timestamp: File.mtime(Rails.root.join("docs/#{doc}")) }
    end
  end

  def self.find(param)
    # search for .md and .html files in docs folder
    name = all.find { |doc| doc.match(/\A#{param}/i) }
    if name.present?
      new(name)
    else
      OpenStruct.new(id: nil, title: nil, layout: nil, content: nil, timestamp: nil)
    end
  end

  def initialize(name)
    file = IO.read(Rails.root.join("docs/#{name}"))

    if File.extname(name) == ".html"
      content = file
      title = "Style Guide"
      layout = "style_guide"
    elsif (md = file.match(/^(?<metadata>---\s*\n.*?\n?)^(---\s*$)/m))
      content = md.post_match
      metadata = YAML.load(md[:metadata])
      title = metadata["title"]
      layout = metadata["layout"]
    end

    @id = File.basename(name, ".*")
    @content = content || ""
    @title = title || "No title"
    @layout = layout || "page"
    @updated_at =  File.mtime(Rails.root.join("docs/#{name}"))
  end

  # split content into array by h2 header
  def content_list
    content.split("\n## ").reduce([]) do |sum, s|
      if s.blank?
        sum
      else
        item = s.split("\n", 2)
        subtitle = item[0].sub(/\((.*)\)/, '<small class="pull-right">\1</small>')
        sum << { subtitle: subtitle, content: item[1].to_s.strip }
      end
    end
  end

  # parse content generated by hologram gem
  # modified from http://stackoverflow.com/questions/3484874/how-to-split-a-html-document-using-nokogiri
  def style_list
    doc = Nokogiri::HTML::fragment(content)
    doc.children.reduce([]) do |chapters, child|
      chapters << { :subtitle => child.inner_text, :content => '' } if child.name == 'h1'
      if child.name != 'h1'
        child = child.to_html.gsub("<br/>", "")
        chapters.last[:content] << child
      end
      chapters
    end
  end

  def timestamp
    updated_at.utc.iso8601
  end

  def cache_key
    ActiveSupport::Cache.expand_cache_key ["doc", id, timestamp]
  end
end
