#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# gitum - Git Upstream Manager.
# Copyright (C) 2012  Pavel Shilovsky <piastry@etersoft.ru>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

from gitupstream import *
import sys
import argparse

def main():
	parser = argparse.ArgumentParser(description='Git Upstream Manager')
	parser.add_argument('--repo',
		help='path to the gitum repo (does not take affect in clone command)')
	subparsers = parser.add_subparsers(dest='command_name')

	merge_p = subparsers.add_parser('merge')
	gr_merge = merge_p.add_mutually_exclusive_group()
	merge_p.add_argument('--track', action='store_true', help='save the branch to use by default')
	gr_merge.add_argument('--continue', action='store_true', help='continue a merge process')
	gr_merge.add_argument('--skip', action='store_true',
		help='skip the current patch in rebase and continue a merge process')
	gr_merge.add_argument('--abort', action='store_true', help='abort a merge process')
	gr_merge.add_argument('--branch', help='local/remote branch to merge from')

	update_p = subparsers.add_parser('update')
	update_p.add_argument('--message', metavar='text',
			help='specify the current branch commit message')

	create_p = subparsers.add_parser('create')
	create_p.add_argument('--remote', metavar='server/branch',
				help='remote branch to track with')
	create_p.add_argument('--current', metavar='branch',
				help='current development branch')
	create_p.add_argument('--upstream', metavar='branch',
				help='copy of tracked upstream branch')
	create_p.add_argument('--rebased', metavar='branch',
				help='branch with our patches on top')
	create_p.add_argument('--patches', metavar='branch',
				help='branch consists of our patches as files')

	remove_p = subparsers.add_parser('remove')
	remove_p.add_argument('--full', action='store_true',
				help='remove branches and config files (default)')
	remove_p.add_argument('--branches', action='store_true',
				help='remove branches')
	remove_p.add_argument('--configfiles', action='store_true',
				help='remove config files')

	restore_p = subparsers.add_parser('restore')
	restore_p.add_argument('--commit', metavar='commit/branch',
			help='restore rebased branch to a given commit')
	restore_p.add_argument('--full', action='store_true',
				help='restore full repository branches')

	clone_p = subparsers.add_parser('clone')
	clone_p.add_argument('git-repo', help='git repo to clone from')
	clone_p.add_argument('repo-dir', nargs='?', help='directory to clone to')

	pull_p = subparsers.add_parser('pull')
	pull_p.add_argument('remote', nargs='?', help='remote repo to pull from')
	pull_p.add_argument('--track', action='store_true',
				help='save the remote to use by default')
	gr_pull = pull_p.add_mutually_exclusive_group()
	gr_pull.add_argument('--resolved', action='store_true',
				help='continue a pull process')
	gr_pull.add_argument('--skip', action='store_true',
				help='skip the current patch and continue a pull process')
	gr_pull.add_argument('--abort', action='store_true',
				help='abort a pull process')

	push_p = subparsers.add_parser('push')
	push_p.add_argument('remote', nargs='?', help='remote repo to push to')
	push_p.add_argument('--track', action='store_true',
				help='save the remote to use by default')

	status_p = subparsers.add_parser('status')

	args = vars(parser.parse_args(sys.argv[1:]))

	if args['repo']:
		path = args['repo']
	else:
		path = '.'

	if not args['command_name'] == 'clone':
		repo = GitUpstream(path, with_log=True)

	if args['command_name'] == 'merge':
		track = args['track']
		try:
			if args['continue']:
				repo.continue_merge('--continue')
			elif args['skip']:
				repo.continue_merge('--skip')
			elif args['abort']:
				repo.abort()
			elif args['branch']:
				repo.merge(args['branch'], track_with=track)
			else:
				repo.merge(track_with=track)
		except GitUmException:
			pass
	elif args['command_name'] == 'update':
		message = args['message'] if args['message'] else ''
		try:
			repo.update(message)
		except GitUmException:
			pass
	elif args['command_name'] == 'create':
		remote = args['remote'] if args['remote'] else REMOTE_BRANCH
		upstream = args['upstream'] if args['upstream'] else UPSTREAM_BRANCH
		rebased = args['rebased'] if args['rebased'] else REBASED_BRANCH
		current = args['current'] if args['current'] else MAINLINE_BRANCH
		patches = args['patches'] if args['patches'] else PATCHES_BRANCH
		try:
			repo.create(remote, upstream, rebased, current, patches)
		except GitUmException:
			pass
	elif args['command_name'] == 'restore':
		rebased_only = True if not args['full'] else False
		commit = args['commit'] if args['commit'] else None
		try:
			repo.restore(commit, rebased_only)
		except GitUmException:
			pass
	elif args['command_name'] == 'remove':
		try:
			if args['branches']:
				repo.remove_branches()
			elif args['configfiles']:
				repo.remove_config_files()
			else:
				repo.remove_all()
		except GitUmException:
			pass
	elif args['command_name'] == 'clone':
		if not args['repo-dir']:
			if args['git-repo'] == '/':
				args['repo-dir'] = '/'
			elif args['git-repo'].endswith('/'):
				args['repo-dir'] = args['git-repo'][:-1].split('/')[-1].split('.git')[0]
			else:
				args['repo-dir'] = args['git-repo'].split('/')[-1].split('.git')[0]
		GitUpstream(repo_path=args['repo-dir'], with_log=True, new_repo=True).clone(args['git-repo'])
	elif args['command_name'] == 'pull':
		track = args['track']
		try:
			if args['resolved']:
				repo.continue_pull('--resolved')
			elif args['skip']:
				repo.continue_pull('--skip')
			elif args['abort']:
				repo.abort(am=True)
			else:
				if args['remote']:
					repo.pull(args['remote'], track_with=track)
				else:
					repo.pull(track_with=track)
		except GitUmException:
			pass
	elif args['command_name'] == 'push':
		track = args['track']
		try:
			if args['remote']:
				repo.push(args['remote'], track_with=track)
			else:
				repo.push(track_with=track)
		except RepoIsDirty:
			pass
	elif args['command_name'] == 'status':
		try:
			repo.status()
		except RepoIsDirty:
			pass

if __name__ == "__main__":
	main()
