require 'sinatra/base'
require 'sinatra/activerecord'
require 'github/markdown'

require_relative './models/note'
require_relative './models/snapshot'

module PushnoteServer
  class App < Sinatra::Base
    register Sinatra::ActiveRecordExtension

    configure do
      set :database_file, 'config/database.yml'
    end

    helpers do
      def date(date)
        date.strftime('%B %d, %Y %T')
      end

      def gfm(input)
        GitHub::Markdown.render_gfm(input)
      end

      def note_path(note)
        "/notes/#{note.id}"
      end

      def code_block(input, language: nil)
        gfm("```#{language}\n#{input}\n```")
      end
    end

    get '/' do
      @welcome = File.read('public/welcome.md')
      erb :index
    end

    get '/notes' do
      erb :notes, locals: { notes: notes }
    end

    get '/notes/:id' do
      erb :note, locals: { notes: notes, note: find_note(params[:id]) }
    end

    put '/:id' do
      find_note(params[:id]).update_attributes!(parsed_body)
      status(200)
    end

    post '/' do
      snapshot_attributes = parsed_body.fetch('snapshot', {})
      snapshot = Snapshot.new(snapshot_attributes)
      Note.create!(
        title: parsed_body.fetch('title', "Untitled"),
        body: parsed_body['body'],
        snapshot: snapshot
      )
      status(201)
    end

    delete '/:id' do
      find_note(params[:id]).destroy!
      status(204)
    end

    protected

    def parsed_body
      @parsed_body ||= begin
        body = request.body.read
        JSON.parse(body)
      end
    end

    def notes
      @notes = Note.order('created_at desc').all
    end

    def find_note(id)
      @note ||= notes.find(id)
    end
  end
end
