require 'cgi'

module Integrity
  module Helpers
    module Urls
      def github_project_url(project, branch=true)
        parts = project.uri.path.split("/").reject { |x| x.empty? }
        user  = parts.first
        repo  = parts.last.chomp(".git")

        if ! branch || project.branch == "master"
          "https://github.com/#{user}/#{repo}"
        else
          "https://github.com/#{user}/#{repo}/compare/" \
            "master...#{project.branch}"
        end
      end

      def github_project_link(project)
        url = github_project_url(project)

        if url.include?("/compare/master")
          "Compare on GitHub"
        else
          "Browse on GitHub"
        end
      end

      def github_commit_url(build)
        github_project_url(build.project, false).to_s +
          "/commit/#{build.sha1}"
      end

      def project_status_image_url(project)
        project_path(project).to_s.concat('.png')
      end

      def project_json_url(project)
        project_path(project).to_s.concat('.json')
      end

      def root_url
        @root_url ||= Addressable::URI.parse(url_for("/", :full))
      end

      def root_path
        @root_path ||= Addressable::URI.parse(url_for("/", :path_only))
      end

      def url(*path)
        root_url.join(path.join("/"))
      end

      def path(*path)
        root_path.join(path.join("/"))
      end

      def project_url(project, *path)
        url(project.permalink, *path)
      end

      def project_path(project, *path)
        path(project.permalink, *path)
      end

      def build_url(build, *path)
        project_url(build.project, "builds", build.id, *path)
      end

      def build_json_url(build, *path)
        build_url(build, *path).to_s.concat('.json')
      end

      def build_path(build, *path)
        project_path(build.project, "builds", build.id, *path)
      end

      def artifact_path(build, artifact, *path)
        build_path(build, 'artifacts', CGI.escape(CGI.escape(artifact)))
      end

      # Copyright (MIT) Eric Kidd -- https://github.com/emk/sinatra-url-for
      #
      # Construct a link to +url_fragment+, which should be given relative to
      # the base of this Sinatra app.  The mode should be either
      # <code>:path_only</code>, which will generate an absolute path within
      # the current domain (the default), or <code>:full</code>, which will
      # include the site name and port number.  (The latter is typically
      # necessary for links in RSS feeds.)  Example usage:
      #
      #   url_for "/"            # Returns "/myapp/"
      #   url_for "/foo"         # Returns "/myapp/foo"
      #   url_for "/foo", :full  # Returns "http://example.com/myapp/foo"
      #--
      # See README.rdoc for a list of some of the people who helped me clean
      # up earlier versions of this code.
      def url_for url_fragment, mode=:path_only
        case mode
        when :path_only
          base = request.script_name
        when :full
          scheme = request.scheme
          if (scheme == 'http' && request.port == 80 ||
              scheme == 'https' && request.port == 443)
            port = ""
          else
            port = ":#{request.port}"
          end
          base = "#{scheme}://#{request.host}#{port}#{request.script_name}"
        else
          raise TypeError, "Unknown url_for mode #{mode}"
        end
        "#{base}#{url_fragment}"
      end
    end
  end
end
