///| Transport utilities (remote parsing)

///|
pub(all) enum RemoteKind {
  Http
  Ssh
  File
} derive(Eq)

///|
pub struct RemoteSpec {
  kind : RemoteKind
  raw : String
  host : String?
  path : String
  base_url : String?
}

///|
pub fn parse_remote(remote : String) -> RemoteSpec {
  if remote.has_prefix("http://") || remote.has_prefix("https://") {
    let base = normalize_http_url(remote)
    return {
      kind: RemoteKind::Http,
      raw: remote,
      host: None,
      path: "",
      base_url: Some(base),
    }
  }
  if remote.has_prefix("ssh://") {
    return parse_ssh_url(remote)
  }
  if remote.has_prefix("file://") {
    let path = String::unsafe_substring(remote, start=7, end=remote.length())
    return {
      kind: RemoteKind::File,
      raw: remote,
      host: None,
      path,
      base_url: None,
    }
  }
  // scp-style: [user@]host:path
  let colon = remote.find(":")
  if colon is Some(idx) && not(remote.has_prefix("/")) {
    let host = String::unsafe_substring(remote, start=0, end=idx)
    let path = String::unsafe_substring(
      remote,
      start=idx + 1,
      end=remote.length(),
    )
    return {
      kind: RemoteKind::Ssh,
      raw: remote,
      host: Some(host),
      path,
      base_url: None,
    }
  }
  // default: local path
  {
    kind: RemoteKind::File,
    raw: remote,
    host: None,
    path: remote,
    base_url: None,
  }
}

///|
fn normalize_http_url(url : String) -> String {
  if url.has_suffix(".git") {
    String::unsafe_substring(url, start=0, end=url.length() - 4)
  } else {
    url
  }
}

///|
fn parse_ssh_url(remote : String) -> RemoteSpec {
  // ssh://[user@]host[:port]/path
  let rest = String::unsafe_substring(remote, start=6, end=remote.length())
  let slash = rest.find("/")
  match slash {
    None =>
      {
        kind: RemoteKind::Ssh,
        raw: remote,
        host: Some(rest),
        path: "",
        base_url: None,
      }
    Some(idx) => {
      let host = String::unsafe_substring(rest, start=0, end=idx)
      let path = String::unsafe_substring(
        rest,
        start=idx + 1,
        end=rest.length(),
      )
      {
        kind: RemoteKind::Ssh,
        raw: remote,
        host: Some(host),
        path,
        base_url: None,
      }
    }
  }
}