import gradio as gr
import tempfile
import os
from git import Repo
from huggingface_hub import HfApi, create_repo, upload_folder
from huggingface_hub.utils import HfHubHTTPError
api = HfApi()


def process(git_repo_url, recursive_bool, space_destination, user_token, space_sdk):
    
    your_username = api.whoami(token=user_token)["name"]

    # Check if space ID is correct including username
    if f"{your_username}/" in str(space_destination):
        print("username is present: good to continue")
    else:
        space_destination = f"{your_username}/{space_destination}"
        print(f"user forgot to mention a username in space_destination: {space_destination}")
    
    # Create a temporary directory to clone the repository
    tmp_dir = tempfile.mkdtemp()
        
    # Clone the Git repository
    repo = Repo.clone_from(git_repo_url, tmp_dir, recursive=recursive_bool)

    # Check if README.md already exists in tmp_dir
    readme_path = os.path.join(tmp_dir, "README.md")
    original_readme_path = os.path.join(tmp_dir, "ORIGINAL_README.md")
    
    # Rename the existing README.md if it exists
    if os.path.exists(readme_path):
        print("Existing README.md found, renaming to ORIGINAL_README.md")
        os.rename(readme_path, original_readme_path)

    # Log the contents of the tmp_dir with its subfolders
    print("Contents of the cloned repository:")
    for root, dirs, files in os.walk(tmp_dir):
        level = root.replace(tmp_dir, '').count(os.sep)
        indent = ' ' * 4 * level
        print(f"{indent}{os.path.basename(root)}/")
        sub_indent = ' ' * 4 * (level + 1)
        for f in files:
            print(f"{sub_indent}{f}")

    try: 
        api.upload_folder(
            folder_path=tmp_dir,
            repo_id=space_destination,
            repo_type="space",
            token=user_token
        )
        return f"Repository cloned ! Find it at hf.co/spaces/{space_destination}"
        
    except HfHubHTTPError as e:
        # Check if the error is a "Repository Not Found" error
        if "404 Client Error" in str(e) and "Repository Not Found" in str(e):
            print("Repository not found. Maybe we should Create the repository...")

            api.create_repo(
                repo_id=space_destination,
                token=user_token,
                private=True,
                repo_type="space",
                space_sdk=space_sdk
            )

            print(f"New space repo created: {space_destination}")

            api.upload_folder(
                folder_path=tmp_dir,
                repo_id=space_destination,
                repo_type="space",
                token=user_token,
                commit_message="Migrated from GitHub",
                ignore_patterns=[
                    "*.git*",
                    "*.DS_Store",
                    "*.env",
                ]
            )
                
            return f"Repository cloned ! Find it at hf.co/spaces/{space_destination}"
        else:
            # Re-raise the exception if it's not a "Repository Not Found" error
            raise e

css = """
div#col-container{
    margin: 0 auto;
    max-width: 720px;
}
"""

with gr.Blocks(css=css) as demo:
    with gr.Column(elem_id="col-container"):
        gr.Markdown("# Clone GitHub repo to Space")
        with gr.Group():
            with gr.Row():
                
                git_repo_url = gr.Textbox(
                    label="Git repo URL to clone",
                    placeholder="https://github.com/username/my-repo.git",
                    scale=3
                )

                recursive_mode = gr.Checkbox(
                    label="Recursive mode",
                    value=False,
                    scale=1
                )
                
            with gr.Row():
                space_destination = gr.Textbox(
                    label="Space ID",
                    placeholder="your_hf_username/space_name"
                )
                user_token = gr.Textbox(
                    label="WRITE permissions HF token",
                    type="password"
                )
            space_sdk = gr.Radio(
                label="Space SDK",
                info="If specified space ID doesn't exist, a new private space will be created. In that case, please choose a SDK",
                choices=["gradio", "docker", "static"],
                value="gradio"
            )
        submit_btn = gr.Button("Clone git repo to my space")
        status = gr.Textbox(
            label="Status"
        )

    submit_btn.click(
        fn=process,
        inputs=[git_repo_url, recursive_mode, space_destination, user_token, space_sdk],
        outputs=[status]
    )

demo.launch(show_error=True)