#!/usr/bin/env python3
import subprocess
from typing import Optional, Tuple
from urllib.parse import urlparse


def strip_git_suffix(path: str) -> str:
    if path.endswith('.git'):
        return path[:-4]
    return path


def parsed_host(parsed) -> Optional[str]:
    if not parsed.hostname:
        return None
    if parsed.port is not None:
        return f'{parsed.hostname}:{parsed.port}'
    return parsed.hostname


def ssh_url(host: str, repo: str) -> str:
    if ':' in host:
        return f'ssh://git@{host}/{repo}.git'
    return f'git@{host}:{repo}.git'


def parse_http_url(url: str) -> Optional[Tuple[str, str]]:
    parsed = urlparse(url)
    if parsed.scheme not in ('http', 'https'):
        return None

    host = parsed_host(parsed)
    if host is None:
        return None

    repo = strip_git_suffix(parsed.path.lstrip('/'))
    if not repo:
        return None
    return host, repo


def parse_ssh_url(url: str) -> Optional[Tuple[str, str]]:
    if url.startswith('ssh://'):
        parsed = urlparse(url)
        host = parsed_host(parsed)
        if host is None:
            return None

        repo = strip_git_suffix(parsed.path.lstrip('/'))
        if not repo:
            return None
        return host, repo

    if '@' not in url or ':' not in url:
        return None

    user_host, repo = url.split(':', 1)
    host = user_host.rsplit('@', 1)[-1]
    repo = strip_git_suffix(repo)
    if repo.startswith('http://') or repo.startswith('https://'):
        return parse_http_url(repo)

    if not host or not repo:
        return None
    return host, repo


print('Checking git repo...')
url = subprocess.check_output('git remote get-url origin'.split()).decode('utf-8').strip()

print(f'Current url: {url}')

if url.startswith('http'):
    print('> HTTP git remote detected, switching to SSH')
    parsed = parse_http_url(url)
    if parsed is None:
        print('Failed to parse HTTP git remote, exiting')
        exit(-1)

    host, repo = parsed
    print(f'> Repo detected: {repo}')
    new_url = ssh_url(host, repo)

elif url.startswith('git@') or url.startswith('ssh://'):
    # git@github.com:hykilpikonna/zshrc.git
    # ssh://git@github.com/hykilpikonna/zshrc.git
    print('> SSH git remote detected, switching to HTTP')
    parsed = parse_ssh_url(url)
    if parsed is None:
        print('Failed to parse SSH git remote, exiting')
        exit(-1)

    host, repo = parsed
    print(f'> Repo detected: {repo}')
    new_url = f'https://{host}/{repo}'

else:
    print('Failed to detect protocol, exiting')
    exit(-1)

print(f'New URL: {new_url}')
print('> Setting new url...')
subprocess.check_call(['git', 'remote', 'set-url', 'origin', new_url])
print('> Done!')
