import requests
from fogbugz import FogBugz
import os
import urllib
import re
import base64
import mimetypes
import time

GITLAB_INSTANCE_URL = 'https://gitlab.com'
GITLAB_API_TOKEN = 'glpat-UkUD1NfVdpvyBACgzMDZ'
GITLAB_PROJECT_ID = 39832947
OWNER = 'fbenoist68'
REPO = 'mobileportal'
S_FOGBUGZ_URL = 'https://mobileretail.fogbugz.com/'
S_EMAIL = 'frederik.benoist@gfi.fr'
S_PASSWORD = '6brOc-gAr6'
MAX_BUGS = 999

def delete_issue(project_id, issue_iid):
    url = f'{GITLAB_INSTANCE_URL}/api/v4/projects/{project_id}/issues/{issue_iid}'

    headers = {
        'Private-Token': GITLAB_API_TOKEN
    }

    response = requests.delete(url, headers=headers)

    if response.status_code == 204:
        ##print(f'Issue with IID {issue_iid} deleted successfully.')
        pass
    else:
        print(f'Failed to delete issue with IID {issue_iid}:', response.text)

def delete_all_issues(project_id):
    url = f'{GITLAB_INSTANCE_URL}/api/v4/projects/{project_id}/issues'
    headers = {
        'Private-Token': GITLAB_API_TOKEN
    }

    remaining_issues = True

    while remaining_issues:
        response = requests.get(url, headers=headers)

        if response.status_code != 200:
            print('Failed to retrieve issues:', response.text)
            break

        issues = response.json()

        if len(issues) == 0:
            # Il n'y a plus d'issues, la suppression est terminée
            print('All issues deleted successfully.')
            break

        for issue in issues:
            delete_issue(project_id, issue['iid'])


def create_gitlab_issue(title, description):
    headers = {
        'Private-Token': GITLAB_API_TOKEN
    }

    data = {
        'title': title,
        'description': description
    }

    url = f'{GITLAB_INSTANCE_URL}/api/v4/projects/{OWNER}%2F{REPO}/issues'
    response = requests.post(url, json=data, headers=headers)

    if response.status_code == 201:
        ##print('Issue created successfully.')
        return response.json()['iid']
    else:
        print('Failed to create issue:', response.text)
        return None

def create_gitlab_comment(issue_number, comment):
    headers = {
        'Private-Token': GITLAB_API_TOKEN
    }

    data = {
        'body': comment
    }

    url = f'{GITLAB_INSTANCE_URL}/api/v4/projects/{OWNER}%2F{REPO}/issues/{issue_number}/notes'
    response = requests.post(url, json=data, headers=headers)

    if response.status_code == 201:
        ##print('Comment created successfully.')
        return response.json()['id']
    else:
        print('Failed to create comment:', response.text)
        return None

def upload_attachment_to_gitlab_project(filename, attachment_data):
    #url = f'{GITLAB_INSTANCE_URL}/api/v4/projects/{OWNER}%2F{REPO}/uploads'
    url = f'{GITLAB_INSTANCE_URL}/api/v4/projects/{GITLAB_PROJECT_ID}/uploads'
    
    # Encode les données binaires en base64
    attachment_data_base64 = base64.b64encode(attachment_data).decode('utf-8')

    # Determine the content type based on the file extension
    mimetype, _ = mimetypes.guess_type(filename)
   
    files = {
        'file': (filename, attachment_data, mimetype or 'application/octet-stream')
    }

    response = requests.post(url, files=files, headers={'Private-Token': GITLAB_API_TOKEN})

    if response.status_code == 201:
        ##print('Attachment uploaded successfully.')

        # Obtenir l'URL de téléchargement depuis la réponse
        download_url = response.json().get('url')
        return download_url
    else:
        print('Failed to upload attachment:', response.text)
        return None

def update_gitlab_comment(comment_id, body):
    headers = {
        'Private-Token': GITLAB_API_TOKEN
    }

    data = {
        'body': body
    }

    url = f'{GITLAB_INSTANCE_URL}/api/v4/projects/{OWNER}%2F{REPO}/issues/comments/{comment_id}'
    response = requests.put(url, json=data, headers=headers)

    if response.status_code == 200:
        # # print('Comment updated successfully.')
        pass
    else:
        print('Failed to update comment:', response.text)

def get_issue_id(issue):
    return int(issue['ixBug'])

def get_event_id(event):
    return int(event['ixBugEvent'])

def main():
    # Utilisation de la fonction pour supprimer toutes les issues d'un projet spécifique
    # delete_all_issues(GITLAB_PROJECT_ID)

    fb = FogBugz(S_FOGBUGZ_URL)
    fb.logon(S_EMAIL, S_PASSWORD)

    resp = fb.search(q='type:"Cases"', cols='ixBug', max=MAX_BUGS)

    for case in sorted(resp.cases.findAll('case'), key=get_issue_id, reverse=False):
        ixBug = int(case['ixBug'])
        if ixBug >= 590:
            time.sleep(1)  # Pause d'une seconde

            print(ixBug)

            respBug = fb.search(q='%s' % ixBug, cols='sTitle,sPersonAssignedTo,sProject,sArea,sCategory,sPriority,events')
            xmlBug = respBug.cases.findAll('case')[0]

            BACKUP_DIR = '/Users/fbenoist68/Code/python/fogbugz/fogbackup'
            BACKUP_DIR += '/' + xmlBug.sProject.string if xmlBug.sProject.string else ''

            if not os.path.exists(BACKUP_DIR):
              os.makedirs(BACKUP_DIR)

            BACKUP_DIR += '/' + str(xmlBug['ixBug'])

            if not os.path.exists(BACKUP_DIR):
              os.makedirs(BACKUP_DIR)

            # Create GitLab issue
            issue_title = f"[FogBugz #{ixBug}] {xmlBug.sTitle.string if xmlBug.sTitle.string else ''}"
            issue_body = f"Assigned To: {xmlBug.sPersonAssignedTo.string}\n"
            issue_body += f"Project: {xmlBug.sProject.string}\n"
            issue_body += f"Area: {xmlBug.sArea.string}\n"
            issue_body += f"Category: {xmlBug.sCategory.string}\n"
            issue_body += f"Priority: {xmlBug.sPriority.string}\n"
        
            issue_number = create_gitlab_issue(issue_title, issue_body)

            if issue_number is not None:
              # Create Gitea comment for each event in reverse !!
              for event in sorted(xmlBug.events.findAll('event'), key=get_event_id, reverse=True):
                  bugEvent = {}
                  bugEvent['ixBugEvent'] = int(event['ixBugEvent'])
                  bugEvent['sVerb'] = event.sVerb.string if event.sVerb.string else ''
                  bugEvent['dt'] = event.dt.string if event.dt.string else ''
                  bugEvent['s'] = event.s.string if event.s.string else ''
                  bugEvent['sChanges'] = event.sChanges.string if event.sChanges.string else ''
                  bugEvent['evtDescription'] = event.evtDescription.string if event.evtDescription.string else ''
                  bugEvent['sPerson'] = event.sPerson.string if event.sPerson.string else ''
                  
                  if event.s and event.s.string:
                    bugEvent['s'] = event.s.string.encode('ascii', 'ignore').decode('utf-8') 
                  else:  
                    bugEvent['s'] = ''

                  if event.sHtml and event.sHtml.string:
                    bugEvent['sHtml'] = event.sHtml.string.encode('ascii', 'ignore').decode('utf-8') 
                  else:  
                    bugEvent['sHtml'] = ''

                  comment = f"Event ID: {bugEvent['ixBugEvent']}\n"
                  comment += f"Date: {bugEvent['dt']}\n"
                  comment += f"Person: {bugEvent['sPerson']}\n"
                  comment += f"Description: {bugEvent['evtDescription']}\n\n\n"

                   # Afficher sHtml s'il n'est pas vide, sinon afficher s
                  content = bugEvent['sHtml'] if bugEvent['sHtml'] else bugEvent['s']
                  comment += f"{content}"

                  new_links = {}

                  for att in event.rgAttachments:
                    # # print('Downloading attachment: ' + att.sFileName.string)
                    str1 = att.sURL.string
                    str2 = 'ixAttachment='
                    loc1 = str1.find(str2) + len(str2)
                    loc2 = str1.find('&amp;sFileName')

                    str3 = ';sFileName='
                    loc3 = str1.find(str3) + len(str3)
                    loc4 = str1.find('&sTicket')

                    theURL = S_FOGBUGZ_URL  # + att.sURL.string
                    theURL += 'default.asp?'
                    theURL += 'ixAttachment=' + str1[loc1:loc2]
                    theURL += '&pg=pgDownload&pgType=pgFile&sFilename=' + str1[loc3:loc4]
                    theURL += '&token=rnl0t87rp34rfg6q0u0rgbhe85v5r8'

                    # fix the replace
                    newFileName = att.sFileName.string.replace('/', '')
                    newFileName = newFileName.replace(':', '')
                    newFileName = BACKUP_DIR + '/' + newFileName
                    # # print(newFileName)
                    urllib.request.urlretrieve(theURL, newFileName)

                    with open(newFileName, 'rb') as attachment_file:
                            attachment_data = attachment_file.read()

                    # # print('Uploading screenshot:', att.sFileName.string)
                    download_url = upload_attachment_to_gitlab_project(att.sFileName.string, attachment_data)

                    if download_url:
                        # Stocker le nouveau lien avec l'ID de l'attachement comme clé
                        new_links[str1[loc1:loc2]] = download_url

                  if new_links:
                    # Remplacer les liens d'attachement dans sHtml avec les nouvelles URLs
                    updated_sHtml = comment

                    for att_id, download_url in new_links.items():
                        # Utilisation d'une expression régulière pour trouver les liens img avec ixAttachment=574
                        pattern = fr'<img[^>]*?ixAttachment={att_id}[^>]*>'

                        # Testez si le motif correspond à la chaîne de texte
                        match = re.search(pattern, updated_sHtml)

                        # Remplacement de tous les liens correspondant au modèle par le nouveau download_url
                        if match:
                            updated_sHtml = re.sub(pattern, f'<img src="{download_url}"/>', updated_sHtml)
                        else:
                            updated_sHtml += f'\n<img src="{download_url}"/>'
                                        
                    comment_id = create_gitlab_comment(issue_number=issue_number, comment=updated_sHtml)
                  else:
                    comment_id = create_gitlab_comment(issue_number=issue_number, comment=comment)
                  
                  # # print('comment id',comment_id);

            fb.view(ixBug=ixBug)
main()         