module StaticMatic
  class Server
    def initialize(staticmatic, default = nil)
      @files = default || Rack::File.new(staticmatic.site_dir)
      @staticmatic = staticmatic
    end

    def call(env)
      @staticmatic.load_helpers
      path_info = env["PATH_INFO"]

      file_dir, file_name, file_ext = expand_path(path_info)

      # remove stylesheets/ directory if applicable
      file_dir.gsub!(/^\/stylesheets\/?/, "")
      
      file_dir = CGI::unescape(file_dir)
      file_name = CGI::unescape(file_name)

      unless file_ext && ["html", "css"].include?(file_ext) &&
          @staticmatic.template_exists?(file_name, file_dir) &&
          File.basename(file_name) !~ /^\_/
        return @files.call(env)
      end

      res = Rack::Response.new
      res.header["Content-Type"] = "text/#{file_ext}"

      begin
        if file_ext == "css"
          res.write @staticmatic.generate_css(file_name, file_dir)
        else
          res.write @staticmatic.generate_html_with_layout(file_name, file_dir)
        end
      rescue StaticMatic::Error => e
        res.write e.message
      end

      res.finish
    end

    # Starts the StaticMatic preview server
    def self.start(staticmatic)
      port = staticmatic.configuration.preview_server_port || 3000

      host = staticmatic.configuration.preview_server_host || ""

      app = Rack::Builder.new do
        use Rack::ShowExceptions
        run StaticMatic::Server.new(staticmatic)
      end
      Rack::Handler::Mongrel.run(app, :Port => port, :Host => host)
    end

    private

    def expand_path(path_info)
      dirname, basename = File.split(path_info)

      extname = File.extname(path_info).sub(/^\./, '')
      filename = basename.chomp(".#{extname}")

      if extname.empty?
        dir = File.join(dirname, filename)
        is_dir = path_info[-1, 1] == '/' || (@staticmatic.template_directory?(dir) && !@staticmatic.template_exists?(filename, dirname))
        if is_dir
          dirname = dir
          filename = 'index'
        end
        extname = 'html'
      end

      [ dirname, filename, extname ]
    end
  end
end