# AUTOGENERATED! DO NOT EDIT! File to edit: 00_core.ipynb (unless otherwise specified).

__all__ = ['check_input', 'get_dest_dir', 'get_repo', 'StopExecution', 'drive_setup', 'change_dir', 'home_dir',
           'run_subprocess', 'clone_new_repo']

# Cell
#test_flag_imports
import os, subprocess, time
from google.colab import drive
from nbdev import *
from nbdev.showdoc import *
from pathlib import Path
from getpass import getpass
import urllib

# Cell
def check_input(type, input):
  "Check the users input and exit cell if invalid"
  if input == "":
    print(f'Error: {type} required ')
    raise StopExecution
  else: return input


def get_dest_dir():
  "Prompts user to input destination dir for repository clone and checks it exists"
  home_dir = "/content/drive/My Drive"
  dir = input(f'Destination directory {home_dir}/')
  dest_dir = home_dir+"/"+dir
  dir_exists = os.path.isdir(dest_dir)
  if dir_exists:
    return dest_dir
  else:
    print(f"Error: Destination directory {dest_dir} does not exist\n")
    raise StopExecution


def get_repo(dir):
  "Prompts user to enter repository name and checks it doesn't already exist in destination dir"
  repo = check_input('repository name', input('Repo name: '))
  repo_path = dir+"/"+repo
  path_exists = os.path.exists(repo_path)
  if path_exists:
    print(f"Error: file/folder {repo} already exists at destination {dir}. Function can only be used to create new repo\n")
    raise StopExecution
  else:
     return repo

# Cell
class StopExecution(Exception):
    "Gracefully exit cell execution"
    def _render_traceback_(self):
        pass

# Cell
def drive_setup():
  "Connect the current Colab instance to the users Google Drive"
  drive.mount('/content/drive', force_remount=True)

# Cell
def change_dir(path):
  "Change directory to 'path'"
  p = Path(path)
  os.chdir(p)

# Cell
def home_dir():
  "Change directory to the users home directory on Google Drive '/content/drive/My Drive'"
  home_dir = "/content/drive/My Drive"
  p = Path(home_dir)
  os.chdir(p)

# Cell
def run_subprocess(cmd):
  "Run a subprocess and return success (0) or error (!0). "
  process = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  process.wait()

  # print any output or errors after converting bytecode to strings
  output, err = process.communicate()
  if output: print(f"{output.decode()}")
  if err: print(f"{err.decode()}")

  # return success (0) or error (!0)
  return process.returncode

# Cell
def clone_new_repo():
  "Clone nbdev GitHUb template repo to google drive and configure"

  print("  IMPORTANT: PLEASE READ:\n\
  nbd_dev does not store user details but user's Github username and password ARE stored in the cloned\n\
  repository on Google Drive to allow automatic authentication from Colaboratory notebooks.Take care\n\
  therefore, NOT to share the cloned repository with anyone as this risks exposing user credentials.\n\
  See documentation for more details.")

  dest_dir = get_dest_dir()
  repo = get_repo(dest_dir)
  user = check_input('Username', input('Username: '))
  user_email = check_input('User email', input('User email: '))
  password = getpass('Password: ')
  password = urllib.parse.quote(password) # to url format

  confirm = input('Confirm and clone y/n?')
  if confirm == 'y':
    print('...')
    # cd into destination directory
    change_dir(dest_dir)

    # clone the repo, purge user passsword immediately and check clone successful
    cmd_string = f'git clone https://{user}:{password}@github.com/{user}/{repo}.git'
    ret = run_subprocess(cmd_string)
    cmd_string, password = None, None
    assert not ret, 'Error: Clone failed. Please review entries and try again. User details purged'
    print(f'Repo {repo} successfully cloned to directory {dest_dir}')

    # wait for new repo dir to appear in users Google Drive then cd into it.
    repo_dir = dest_dir+"/"+repo
    cnt = 0
    while not os.path.exists(repo_dir):
      time.sleep(1)
      cnt += 1
      if cnt == 10:
        print("Unable to continue: Can't locate cloned repo to configure.")
        raise _stop_execution
    print('New repo located. Changing directory to new repo')
    change_dir(repo_dir)
    print(repo_dir)

    # save user email and username into local git repo to identify user to git
    ret_user = run_subprocess(f'git config user.name {user}')
    ret_email = run_subprocess(f'git config user.email {user_email}')
    user, user_email = None, None
    if ret_user or ret_email:
      msg = f'Git configuration failed. Please manually configure the local repo with username and email\n'
    else:
      msg = f'New repo configured with username and email'
    print(msg)

    # install git hooks to automatically clean up notebook metadata
    ret = run_subprocess('nbdev_install_git_hooks')

  # user cancelled
  else:
    cmd_string, password = None, None
    print('Clone cancelled\n')
    raise StopExecution

  return None