#!/usr/bin/python

#       Licensed to the Apache Software Foundation (ASF) under one
#       or more contributor license agreements.  See the NOTICE file
#       distributed with this work for additional information
#       regarding copyright ownership.  The ASF licenses this file
#       to you under the Apache License, Version 2.0 (the
#       "License"); you may not use this file except in compliance
#       with the License.  You may obtain a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#       Unless required by applicable law or agreed to in writing,
#       software distributed under the License is distributed on an
#       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
#       KIND, either express or implied.  See the License for the
#       specific language governing permissions and limitations
#       under the License.

import sys
import getpass
from urlparse import urljoin

from allura.lib import rest_api

SRC_CRED=dict(
        api_key='c03efc6cca1cf78be9e9',
        secret_key='575eda2f25f6490d8cfe5d02f2506c010112894d0ea10660e43157a87a7e620c61ac06397b028af1',
        http_username=raw_input('LDAP username: '),
        http_password=getpass.getpass('LDAP password: '))
SRC_SERVER='https://newforge.sf.geek.net/'
SRC_TOOL='/rest/p/forge/tickets/'

# Credentials for sf-overlords
# DST_CRED=dict(
#     api_key='a4a88c67179137053d70',
#     secret_key='fcc48a0c31459e99a88cc42cdd7f908fad78b283ca30a86caac1ab65036ff71fc195a18e56534dc5')
# DST_SERVER='http://sourceforge.net/'
# DST_TOOL='/rest/p/allura/tickets/'
DST_CRED=dict(
    api_key='aa7244645424513d9636',
    secret_key='cd1d97be98497f7b615b297aa2061177ddf6d42b95a8484193f84690486694234dbf817efc3b2d6e')
DST_SERVER='http://localhost:8080/'
DST_TOOL='/rest/p/test/bugs/'

FAKE_TICKET={
    u'created_date': u'2010-03-08 17:29:42.802000',
    u'assigned_to_id': u'',
    u'assigned_to': u'',
    u'custom_fields': {'_component':'', '_size':0, '_priority':'', '_type':''},
    u'description': u'Ticket was not present in source',
    u'milestone': u'',
    u'reported_by': u'',
    u'reported_by_id': u'',
    u'status': u'closed',
    u'sub_ids': [],
    u'summary': u'Placeholder ticket',
    u'super_id': u'None'}

def main():
    src_cli = rest_api.RestClient(
        base_uri=SRC_SERVER,
        **SRC_CRED)
    dst_cli = rest_api.RestClient(
        base_uri=DST_SERVER,
        **DST_CRED)
    src = TicketAPI(src_cli, SRC_TOOL)
    dst = TicketAPI(dst_cli, DST_TOOL)
    for ticket in src.iter_tickets(min_ticket=3, check=True):
        print 'Migrating ticket %s:\n%s' % (ticket['ticket_num'], ticket)
        print 'Create ticket on %s' % DST_SERVER
        dst.create_ticket(ticket)
        print 'Create discussion on %s' % DST_SERVER
        src_thread = src.load_thread(ticket)
        if not src_thread or not src_thread['posts']:
            print '... no posts'
            continue
        dst_thread = dst.load_thread(ticket)
        slug_map = {}
        for post in src.iter_posts(src_thread):
            print '... migrate post %s:\n%r' % (post['slug'], post['text'])
            dst.create_post(dst_thread, post, slug_map)

class TicketAPI(object):

    def __init__(self, client, path):
        self.client = client
        self.path = path

    def iter_tickets(self, min_ticket=1, max_ticket=None, check=False):
        if check:
            tickets = self.client.request('GET', self.path)['tickets']
            valid_tickets = set(t['ticket_num'] for t in tickets)
            max_valid_ticket = max(valid_tickets)
        cur_ticket = min_ticket
        while True:
            if check and cur_ticket not in valid_tickets:
                if cur_ticket > max_valid_ticket: break
                yield dict(FAKE_TICKET, ticket_num=cur_ticket)
                cur_ticket += 1
                continue
            ticket = self.client.request('GET', self.ticket_path(cur_ticket))['ticket']
            if ticket is None: break
            yield ticket
            cur_ticket += 1
            if max_ticket and cur_ticket > max_ticket: break

    def load_thread(self, ticket):
        discussion = self.client.request('GET', self.discussion_path())['discussion']
        for thd in discussion['threads']:
            if thd['subject'].startswith('#%d ' % ticket['ticket_num']):
                break
        else:
            return None
        thread = self.client.request(
            'GET',self.thread_path(thd['_id']))['thread']
        return thread

    def iter_posts(self, thread):
        for p in sorted(thread['posts'], key=lambda p:p['slug']):
            post = self.client.request(
                'GET', self.post_path(thread['_id'], p['slug']))['post']
            yield post

    def create_ticket(self, ticket):
        ticket = dict(ticket, labels='')
        ticket['description'] = 'Created by: %s\nCreated date: %s\nAssigned to:%s\n\n%s' % (
            ticket['reported_by'], ticket['created_date'], ticket['assigned_to'], ticket['description'])
        for bad_key in ('assigned_to_id', 'created_date', 'reported_by', 'reported_by_id', 'super_id', 'sub_ids', '_id'):
            if bad_key in ticket:
                del ticket[bad_key]
        ticket.setdefault('labels', '')
        ticket['custom_fields'].setdefault('_size', 0)
        ticket['custom_fields'].setdefault('_priority', 'low')
        ticket['custom_fields'].setdefault('_type', 'Bug')
        ticket['custom_fields'].setdefault('_type', 'Component')
        if ticket['custom_fields']['_size'] is None:
            ticket['custom_fields']['_size'] = 0
        if ticket['milestone'] not in ('backlog', 'public2',  'GA', 'post-GA'):
            ticket['milestone'] = ''
        if ticket['status'] not in 'open in-progress code-review validation closed'.split():
            ticket['status'] = 'open'
        r = self.client.request('POST', self.new_ticket_path(), ticket_form=ticket)
        self.client.request(
            'POST', self.ticket_path(r['ticket']['ticket_num'], 'save'),
            ticket_form=ticket)

    def create_post(self, thread, post, slug_map):
        text = 'Post by %s:\n%s' % (
            post['author'], post['text'])
        if '/' in post['slug']:
            parent_post = slug_map[post['slug'].rsplit('/', 1)[0]]
            new_post = self.client.request(
                'POST', self.post_path(thread['_id'], parent_post, 'reply'),
                text=text)['post']
        else:
            new_post = self.client.request(
                'POST', self.thread_path(thread['_id'], 'new'),
                text=text)['post']
        slug_map[post['slug']] = new_post['slug']
        return new_post

    def new_ticket_path(self):
        return urljoin(self.path, 'new')

    def ticket_path(self, ticket_num, suffix=''):
        return urljoin(self.path, str(ticket_num)) + '/' + suffix

    def discussion_path(self):
        return '%s_discuss/' % (self.path)

    def thread_path(self, thread_id, suffix=''):
        return '%s_discuss/thread/%s/%s' % (self.path, thread_id, suffix)

    def post_path(self, thread_id, post_slug, suffix=''):
        return '%s_discuss/thread/%s/%s/%s' % (self.path, thread_id, post_slug, suffix)

def pm(etype, value, tb): # pragma no cover
    import pdb, traceback
    try:
        from IPython.ipapi import make_session; make_session()
        from IPython.Debugger import Pdb
        sys.stderr.write('Entering post-mortem IPDB shell\n')
        p = Pdb(color_scheme='Linux')
        p.reset()
        p.setup(None, tb)
        p.print_stack_trace()
        sys.stderr.write('%s: %s\n' % ( etype, value))
        p.cmdloop()
        p.forget()
        # p.interaction(None, tb)
    except ImportError:
        sys.stderr.write('Entering post-mortem PDB shell\n')
        traceback.print_exception(etype, value, tb)
        pdb.post_mortem(tb)

sys.excepthook = pm

if __name__ == '__main__':
    main()
