#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
stashcli
~~~~~~~~~
"""

import stashy
import sys
import os
import click
import tempfile
import git
from stashcli import hipchat
from stashcli import errors
from stashcli.template import Template
from stashcli.config import Config
from stashcli.pullrequest import PullRequest
from subprocess import call

reload(sys)
sys.setdefaultencoding('utf8')

EDITOR   = os.environ.get('EDITOR','vim')
stash    = None
git_repo = git.Repo(os.getcwd())

'''
Check configuration & git repository before
continuing
'''
try:
    conf     = Config()
    template = Template.fromFile(conf.getTemplateFilePath())
except Exception as e:
    click.echo(click.style(unicode(e), fg='red'))
    sys.exit(1)

'''
Command definition to make pull-requests
'''
@click.command()
@click.option('--title', prompt="Title", help='Pull-request title')
@click.option('--description', prompt="Description", default=template, help='Description to be set for the pull-request.\
    \nDefault: template file specified within .git/config will be read and parsed.')
@click.option('--src-branch', prompt="Source branch", default=git_repo.head.ref, help='Source branch')
@click.option('--dest-branch', prompt="Destination branch", default=conf.getMergeDestination(), help='Target branch')
@click.option('--reviewers', prompt="Reviewers", default=conf.getReviewers(None), help='Target branch')
@click.option('--state', prompt="Pull-request state", default='OPEN', help='Initial state of the pull-request')
@click.option('--multiline/--no-multiline', default=True, help='Open content of the description using the default editor before pushing.')
def pr(title, description, src_branch, dest_branch, reviewers, state, multiline):

    '''Program to create pull-requests in a Atlassian Stash repository.'''

    try:
        stash = stashy.connect(conf.getStashUrl(), conf.getUsername(), conf.getPassword())

        # assign template content
        template = Template(description)

        # Replace template placeholders with input from the user
        for placeholder in template.getPlaceholders():
            value = click.prompt(placeholder)
            template.setPlaceholderValue(placeholder, value)

        # Get project and repository name
        project = conf.getProject()
        repository = conf.getRepo()

        # Open description in the editor if multiline is configured
        if (multiline == True):
            tmp = tempfile.NamedTemporaryFile(suffix=".tmp")
            try:
                tmp.write(unicode(template))
                tmp.flush()
                call([EDITOR, tmp.name])
                f = open(tmp.name, 'r')
                description = f.read()
            finally:
                tmp.close()
        else:
            description = unicode(template)

        pr = PullRequest(stash)
        pr.setTitle(title)
        pr.setDescription(description)
        pr.setSourceBranch(src_branch)
        pr.setDestinationBranch(dest_branch)
        pr.setReviewers(conf.splitReviewers(reviewers))
        pr.setProject(project)
        pr.setRepository(repository)

        pr_response = pr.create(state)

        click.echo('')
        click.echo(click.style('Sending pull-request...', fg='yellow'))

        # CLI print
        click.echo(click.style('Stash URL: ' + pr_response.getUrl(), fg='green'))
        click.echo(click.style('✅  Pull request #' + pr_response.getId() + ' - "' + \
            pr_response.getTitle() + '" created successfully.', fg='green'))

        # Integrate with Hipchat if enabled
        if (conf.isHipchatEnabled()):
            message = '🔀 ' + pr_response.getAuthor() + ' added pull-request <a href="' + \
                pr_response.getUrl() + '">#' + pr_response.getId() + ' ' + pr_response.getTitle() + '</a>'
            chat = hipchat.Notifier(conf.getHipchatToken())
            chat.notify(conf.getHipchatRoom(), conf.getHipchatAgent(), message,
                hipchat.Format.HTML, hipchat.MsgColour.PURPLE)
            click.echo(click.style('✅  Published pull-request reference in Hipchat.', fg='green'))

        click.echo('')
        sys.exit(0)
    except git.exc.InvalidGitRepositoryError as e:
        click.echo(click.style('Directory you are running stashcli command is not a git repository.', fg='red'))
        sys.exit(1)
    except errors.DuplicatePullRequest as e:
        click.echo(click.style(unicode(e), fg='yellow'))
        sys.exit(1)
    except errors.EmptyPullRequest as e:
        click.echo(click.style(unicode(e), fg='green'))
        sys.exit(1)
    except KeyboardInterrupt as e:
        click.echo("\nCancelled")
        sys.exit(2)
    except Exception as e:
        click.echo(click.style(unicode(e), fg='red'))
        sys.exit(1)

if __name__ == '__main__':
    pr()
