#!/usr/bin/env python3.6
import git
import subprocess
import semantic_version
import json
import pprint
import requests
import argparse
from shutil import copyfile
from variables import *
import cookbook_sync

# Declare globar vars, cookbooks_todo.txt is precompiled list of cookbooks
# to work on
cookbooks = open("{0}/cookbooks_todo.txt".format(chef_dir), 'r')
pp = pprint.PrettyPrinter(indent=4)
branch_name = "bugfix/updateci"

def create_branch(i):
    # This will create a new branch off the HEAD of the master branch
    print("Creating branch to add new CI config")
    g.checkout('HEAD', b=branch_name)


def version_bump(i):
    version = None
    old_version = None
    new_version = None
    # sanitize metadata.rb
    subprocess.run('rubocop -a metadata.rb',
               cwd='{0}/cookbooks/{1}'.format(chef_dir, i), shell=True)

    with open("{0}/cookbooks/{1}/metadata.rb".format(chef_dir, i), 'r') as infile:
        data = infile.read()
        print("Opened metadata.rb")
  
    for line in data.split("\n"):
        if line.startswith('version'):
            version = line.split(" ", 1)[1].strip()
            old_version = semantic_version.Version(version.strip("\'"))
            new_version = old_version.next_patch()

    return data.replace(version, "'{0}'".format(str(new_version)))


def write_metadata(new_version, i):
    with open("{0}/cookbooks/{1}/metadata.rb".format(chef_dir, i), 'w') as outfile:
        outfile.write(new_version)


def push_branch(i):
    # Add, commit, then push
    g.add(["{0}/cookbooks/{1}/*".format(chef_dir, i)])
    g.commit(m="updated CI conf")
    g.push('--set-upstream', 'origin', branch_name)
    print("Bugfix branch pushed to gitlab")


def get_project_id(i):
    get_id = requests.get("{0}/api/v3/projects/chef%2F{1}".format(gitlab_url, i),
                          headers={"PRIVATE-TOKEN": "{0}".format(private_token)})
    return get_id

def create_pr(get_id):
    project_data = get_id.json()
    print("Project ID: {0}".format(project_data['id']))
    merge_req = requests.post(("{0}/api/v3/projects/{1}/merge_requests?"
                               "source_branch={2}&target_branch=master&title={2}").format(gitlab_url, project_data['id'], branch_name),
                              headers={"PRIVATE-TOKEN": "{0}".format(private_token)})
    print("Merge Request submitted to Gitlab")


def get_pr_ids(i):
    # Get merge request ID and IID
    pr_ids = requests.get("{0}/api/v3/projects/chef%2F{1}/merge_requests?state=opened".format(gitlab_url, i),
                          headers={"PRIVATE-TOKEN": "{0}".format(private_token)})
    return pr_ids


def accept_pr(pr_ids, i):
    merge_data = pr_ids.json()
    accept_req = requests.put(("{0}/api/v3/projects/chef%2F{1}/merge_requests/{2}/merge").format(gitlab_url, i, merge_data[0]['id']),
                              headers={"PRIVATE-TOKEN": "{0}".format(private_token)})
    print("Merge request accepted!\n")


for i in cookbooks:
    i = i.rstrip()
    g = git.cmd.Git("{0}/cookbooks/{1}".format(chef_dir, i))

    cookbook_sync.cookbook_sync(i)
    create_branch(i)
    new_version = version_bump(i)
    write_metadata(new_version, i)

    copyfile("{0}/.gitlab-ci.yml-example".format(chef_dir),
             "{0}/cookbooks/{1}/.gitlab-ci.yml".format(chef_dir, i))

    push_branch(i)
    get_id = get_project_id(i)
    create_pr(get_id)
    pr_ids = get_pr_ids(i)
    accept_pr(pr_ids, i)

    g.checkout('master')
