#!/usr/bin/env python

# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# For Spreadsheets:
try:
  from xml.etree import ElementTree
except ImportError:
  from elementtree import ElementTree
import gdata.spreadsheet.service
import gdata.service
import atom.service
import gdata.spreadsheet
import atom

# For Issue Tracker:
import gdata.projecthosting.client
import gdata.projecthosting.data
import gdata.gauth
import gdata.client
import gdata.data
import atom.http_core
import atom.core

# For this script:
import getpass
from optparse import OptionParser
import pickle
from sets import Set

# Settings
credentials_store = 'creds.dat'

class Merger(object):
  def __init__(self, ss_key, ss_ws_key, tracker_message, tracker_project,
               debug, pretend):
    self.ss_key = ss_key
    self.ss_ws_key = ss_ws_key
    self.tracker_message = tracker_message
    self.tracker_project = tracker_project
    self.debug_enabled = debug
    self.pretend = pretend
    self.user_agent = 'adlr-tracker-spreadsheet-merger'
    self.it_keys = ['id', 'owner', 'status', 'title']

  def debug(self, message):
    """Prints message if debug mode is set."""
    if self.debug_enabled:
      print message

  def print_feed(self, feed):
    'Handy for debugging'
    for i, entry in enumerate(feed.entry):
      print 'id:', entry.id
      if isinstance(feed, gdata.spreadsheet.SpreadsheetsCellsFeed):
        print '%s %s\n' % (entry.title.text, entry.content.text)
      elif isinstance(feed, gdata.spreadsheet.SpreadsheetsListFeed):
        print '%s %s %s' % (i, entry.title.text, entry.content.text)
        # Print this row's value for each column (the custom dictionary is
        # built using the gsx: elements in the entry.)
        print 'Contents:'
        for key in entry.custom:
          print '  %s: %s' % (key, entry.custom[key].text)
        print '\n',
      else:
        print '%s %s\n' % (i, entry.title.text)


  def tracker_login(self):
    """Logs user into Tracker, using cached credentials if possible.
    Saves credentials after login."""
    self.it_client = gdata.projecthosting.client.ProjectHostingClient()
    self.it_client.source = self.user_agent

    self.load_creds()

    if self.tracker_token and self.tracker_user:
      print 'Using existing credential for tracker login'
      self.it_client.auth_token = self.tracker_token
    else:
      self.tracker_user = raw_input('Issue Tracker Login:')
      password = getpass.getpass('Password:')
      self.it_client.ClientLogin(self.tracker_user, password,
                                 source=self.user_agent, service='code',
                                 account_type='GOOGLE')
      self.tracker_token = self.it_client.auth_token
      self.store_creds()

  def spreadsheet_login(self):
    """Logs user into Google Spreadsheets, using cached credentials if possible.
    Saves credentials after login."""
    self.gd_client = gdata.spreadsheet.service.SpreadsheetsService()
    self.gd_client.source = self.user_agent

    self.load_creds()
    if self.docs_token:
      print 'Using existing credential for docs login'
      self.gd_client.SetClientLoginToken(self.docs_token)
    else:
      self.gd_client.email = raw_input('Google Docs Login:')
      self.gd_client.password = getpass.getpass('Password:')
      self.gd_client.ProgrammaticLogin()
      self.docs_token = self.gd_client.GetClientLoginToken()
      self.store_creds()

  def fetch_spreadsheet_issues(self):
    """Fetches all issues from the user-specified spreadsheet. Returns
    them as an array or dictionaries."""
    feed = self.gd_client.GetListFeed(self.ss_key, self.ss_ws_key)
    issues = []
    for entry in feed.entry:
      issue = {}
      for key in entry.custom:
        issue[key] = entry.custom[key].text
      issue['__raw_entry'] = entry
      issues.append(issue)
    return issues

  def ids_for_spreadsheet_issues(self, ss_issues):
    """Returns a Set of strings, each string an id from ss_issues"""
    ret = Set()
    for ss_issue in ss_issues:
      ret.add(ss_issue['id'])
    return ret

  def tracker_issues_for_query_feed(self, feed):
    """Converts a feed object from a query to a list of tracker issue
    dictionaries."""
    issues = []
    for issue in feed.entry:
      issue_dict = {}
      issue_dict['labels'] = [label.text for label in issue.label]
      issue_dict['id'] = issue.id.text.split('/')[-1]
      issue_dict['title'] = issue.title.text
      issue_dict['status'] = issue.status.text
      if issue.owner:
        issue_dict['owner'] = issue.owner.username.text
      issues.append(issue_dict)
    return issues

  def fetch_tracker_issues(self, ss_issues):
    """Fetches all relevant issues from traacker and returns them as an array
    of dictionaries. Relevance is:
    - has an ID that's in ss_issues, OR
    - (is Area=Installer AND status is open).
    Open status is one of: Unconfirmed, Untriaged, Available, Assigned,
    Started, Upstream"""
    issues = []
    got_results = True
    index = 1
    while got_results:
      query = gdata.projecthosting.client.Query(label='Area-Installer',
                                                max_results=50,
                                                start_index=index)
      feed = self.it_client.get_issues('chromium-os', query=query)
      if not feed.entry:
        got_results = False
      index = index + len(feed.entry)
      issues.extend(self.tracker_issues_for_query_feed(feed))
    # Now, remove issues that are open or in ss_issues.
    ss_ids = self.ids_for_spreadsheet_issues(ss_issues)
    open_statuses = ['Unconfirmed', 'Untriaged', 'Available', 'Assigned',
                     'Started', 'Upstream']
    new_issues = []
    for issue in issues:
      if issue['status'] in open_statuses or issue['id'] in ss_ids:
        new_issues.append(issue)
      # Remove id from ss_ids, if it's there
      ss_ids.discard(issue['id'])
    issues = new_issues

    # Now, for each ss_id that didn't turn up in the query, explicitly add it
    for id_ in ss_ids:
      query = gdata.projecthosting.client.Query(issue_id=id_,
                                                max_results=50,
                                                start_index=index)
      feed = self.it_client.get_issues('chromium-os', query=query)
      if not feed.entry:
        print 'No result for id', id_
        continue
      issues.extend(self.tracker_issues_for_query_feed(feed))

    return issues

  def store_creds(self):
    """Stores login credentials to disk."""
    obj = {}
    if self.docs_token:
      obj['docs_token'] = self.docs_token
    if self.tracker_token:
      obj['tracker_token'] = self.tracker_token
    if self.tracker_user:
      obj['tracker_user'] = self.tracker_user
    try:
      f = open(credentials_store, 'w')
      pickle.dump(obj, f)
      f.close()
    except IOError:
      print 'Unable to store credentials'

  def load_creds(self):
    """Loads login credentials from disk."""
    self.docs_token = None
    self.tracker_token = None
    self.tracker_user = None
    try:
      f = open(credentials_store, 'r')
      obj = pickle.load(f)
      f.close()
      if obj.has_key('docs_token'):
        self.docs_token = obj['docs_token']
      if obj.has_key('tracker_token'):
        self.tracker_token = obj['tracker_token']
      if obj.has_key('tracker_user'):
        self.tracker_user = obj['tracker_user']
    except IOError:
      print 'Unable to load credentials'

  def browse(self):
    """Browses Spreadsheets to help the user find the spreadsheet and
    worksheet keys"""
    print 'Browsing spreadsheets...'

    if self.ss_key and self.ss_ws_key:
      print 'You already passed in --ss_key and --ss_ws_key. No need to browse.'
      return

    print 'Logging in...'
    self.spreadsheet_login()

    if not self.ss_key:
      print 'Fetching spreadsheets...'
      feed = self.gd_client.GetSpreadsheetsFeed()
      print ''
      print 'Spreadsheet key - Title'
      for entry in feed.entry:
        key = entry.id.text.split('/')[-1]
        title = entry.title.text
        print '"%s" - "%s"' % (key, title)
      print ''
      print 'Done. Rerun with --ss_key=KEY to browse a list of worksheet keys.'
    else:
      print 'Fetching worksheets for spreadsheet', self.ss_key
      feed = self.gd_client.GetWorksheetsFeed(self.ss_key)
      for entry in feed.entry:
        key = entry.id.text.split('/')[-1]
        title = entry.title.text
        print ''
        print 'Worksheet key - Title'
        print '"%s" - "%s"' % (key, title)
      print ''
      print 'Done. You now have keys for --ss_key and --ss_ws_key.'

  def tracker_issue_for_id(self, issues, id_):
    """Returns the element of issues which has id_ for the key 'id'"""
    for issue in issues:
      if issue['id'] == id_:
        return issue
    return None

  def spreadsheet_issue_to_tracker_dict(self, ss_issue):
    """Converts a spreadsheet issue to the dict format that is used to
    represent a tracker issue."""
    ret = {}
    ret['project'] = self.tracker_project
    ret['title'] = ss_issue['title']
    ret['summary'] = self.tracker_message
    ret['owner'] = ss_issue['owner']
    if ss_issue.get('status') is not None:
      ret['status'] = ss_issue['status']
    ret['labels'] = []
    for (key, value) in ss_issue.items():
      if key.endswith('-') and (value is not None):
        ret['labels'].append(key.title() + value)
    return ret

  def label_from_prefix(self, prefix, corpus):
    """Given a corpus (array of lable strings), return the first label
    that begins with the specified prefix."""
    for label in corpus:
      if label.startswith(prefix):
        return label
    return None

  def update_spreadsheet_issue_to_tracker_dict(self, ss_issue, t_issue):
    """Updates a given tracker issue with data from the spreadsheet issue."""
    ret = {}
    ret['title'] = ss_issue['title']
    ret['id'] = ss_issue['id']
    ret['summary'] = self.tracker_message
    if ss_issue['status'] != t_issue['status']:
      ret['status'] = ss_issue['status']

    if ss_issue.get('owner'):
      if (not t_issue.has_key('owner')) or \
        (ss_issue['owner'] != t_issue['owner']):
        ret['owner'] = ss_issue['owner']
    # labels
    ret['labels'] = []
    for (key, value) in ss_issue.items():
      caps_key = key.title()
      if not caps_key.endswith('-'):
        continue
      ss_label = None
      if value:
        ss_label = caps_key + value.title()
      t_label = self.label_from_prefix(caps_key, t_issue['labels'])

      if t_label is None and ss_label is None:
        # Nothing
        continue

      if (t_label is not None) and \
        ((ss_label is None) or (ss_label != t_label)):
        ret['labels'].append('-' + t_label)

      if (ss_label is not None) and \
        ((t_label is None) or (t_label != ss_label)):
        ret['labels'].append(ss_label)
    return ret

  def tracker_issue_has_changed(self, t_issue, ss_issue):
    """Returns True iff ss_issue indicates changes in t_issue that need to be
    committed up to the Issue Tracker."""
    if t_issue is None:
      return True
    potential_commit = \
      self.update_spreadsheet_issue_to_tracker_dict(ss_issue, t_issue)

    if potential_commit.has_key('status') or \
      potential_commit.has_key('owner') or \
      (len(potential_commit['labels']) > 0):
      return True
    if potential_commit['title'] != t_issue['title']:
      return True
    return False

  def spreadsheet_to_tracker_commits(self, ss_issues, t_issues):
    """Given the current state of all spreadsheet issues and tracker issues,
    returns a list of all commits that need to go to tracker to get it in
    line with the spreadsheet."""
    ret = []
    for ss_issue in ss_issues:
      t_issue = self.tracker_issue_for_id(t_issues, ss_issue['id'])
      commit = {}
      # TODO see if an update is needed at all
      if t_issue is None:
        commit['type'] = 'append'
        commit['dict'] = self.spreadsheet_issue_to_tracker_dict(ss_issue)
        commit['__ss_issue'] = ss_issue
      else:
        if not self.tracker_issue_has_changed(t_issue, ss_issue):
          continue
        commit['type'] = 'update'
        commit['dict'] = \
          self.update_spreadsheet_issue_to_tracker_dict(ss_issue, t_issue)
      ret.append(commit)
    return ret

  def fetch_issues(self):
    """Logs into Docs/Tracker, and fetches spreadsheet and tracker issues"""
    print 'Logging into Docs...'
    self.spreadsheet_login()
    print 'Logging into Tracker...'
    self.tracker_login()

    print 'Fetching spreadsheet issues...'
    ss_issues = self.fetch_spreadsheet_issues()
    self.debug('Spreadsheet issues: %s' % ss_issues)
    print 'Fetching tracker issues...'
    t_issues = self.fetch_tracker_issues(ss_issues)
    self.debug('Tracker issues: %s' % t_issues)
    return (t_issues, ss_issues)

  def spreadsheet_to_tracker(self):
    """High-level function to manage migrating data from the spreadsheet
    to Tracker."""
    (t_issues, ss_issues) = self.fetch_issues()
    print 'Calculating deltas...'
    commits = self.spreadsheet_to_tracker_commits(ss_issues, t_issues)
    self.debug('got commits: %s' % commits)
    if not commits:
      print 'No deltas. Done.'
      return

    for commit in commits:
      dic = commit['dict']
      labels = dic.get('labels')
      owner = dic.get('owner')
      status = dic.get('status')

      if commit['type'] == 'append':
        print 'Creating new tracker issue...'
        if self.pretend:
          print '(Skipping because --pretend is set)'
          continue
        created = self.it_client.add_issue(self.tracker_project,
                                           dic['title'],
                                           self.tracker_message,
                                           self.tracker_user,
                                           labels=labels,
                                           owner=owner,
                                           status=status)
        issue_id = created.id.text.split('/')[-1]
        print 'Created issue with id:', issue_id
        print 'Write id back to spreadsheet row...'
        raw_entry = commit['__ss_issue']['__raw_entry']
        ss_issue = commit['__ss_issue']
        del ss_issue['__raw_entry']
        ss_issue.update({'id': issue_id})
        self.gd_client.UpdateRow(raw_entry, ss_issue)
        print 'Done.'
      else:
        print 'Updating issue with id:', dic['id']
        if self.pretend:
          print '(Skipping because --pretend is set)'
          continue
        self.it_client.update_issue(self.tracker_project,
                                    dic['id'],
                                    self.tracker_user,
                                    comment=self.tracker_message,
                                    status=status,
                                    owner=owner,
                                    labels=labels)
        print 'Done.'

  def spreadsheet_issue_for_id(self, issues, id_):
    """Given the array of spreadsheet issues, return the first one that
    has id_ for the key 'id'."""
    for issue in issues:
      if issue['id'] == id_:
        return issue
    return None

  def value_for_key_in_labels(self, label_array, prefix):
    """Given an array of labels and a prefix, return the non-prefix part
    of the first label that has that prefix. E.g. if label_array is
    ["Mstone-R7", "Area-Installer"] and prefix is "Area-", returns
    "Installer"."""
    for label in label_array:
      if label.startswith(prefix):
        return label[len(prefix):]
    return None

  def tracker_issue_to_spreadsheet_issue(self, t_issue, ss_keys):
    """Converts a tracker issue to the format used by spreadsheet, given
    the row headings ss_keys."""
    new_row = {}
    for key in ss_keys:
      if key.endswith('-'):
        # label
        new_row[key] = self.value_for_key_in_labels(t_issue['labels'],
                                                    key.title())
      # Special cases
      if key in self.it_keys and key in t_issue:
        new_row[key] = t_issue[key]
    return new_row

  def spreadsheet_row_needs_update(self, ss_issue, t_issue):
    """Returns True iff the spreadsheet issue passed in needs to be updated
    to match data in the tracker issue."""
    new_ss_issue = self.tracker_issue_to_spreadsheet_issue(t_issue,
                                                           ss_issue.keys())
    for key in new_ss_issue.keys():
      if not ss_issue.has_key(key):
        continue
      if new_ss_issue[key] != ss_issue[key]:
        return True
    return False

  def tracker_to_spreadsheet_commits(self, t_issues, ss_issues):
    """Given the current set of spreadsheet and tracker issues, computes
    commits needed to go to Spreadsheets to get the spreadsheet in line
    with what's in Tracker."""
    ret = []
    keys = ss_issues[0].keys()
    for t_issue in t_issues:
      commit = {}
      ss_issue = self.spreadsheet_issue_for_id(ss_issues, t_issue['id'])
      if ss_issue is None:
        # New issue
        commit['new_row'] = self.tracker_issue_to_spreadsheet_issue(t_issue,
                                                                    keys)
        commit['type'] = 'append'
      elif self.spreadsheet_row_needs_update(ss_issue, t_issue):
        commit['__raw_entry'] = ss_issue['__raw_entry']
        del ss_issue['__raw_entry']
        ss_issue.update(self.tracker_issue_to_spreadsheet_issue(t_issue, keys))
        commit['dict'] = ss_issue
        commit['type'] = 'update'
      else:
        continue
      ret.append(commit)
    return ret

  def tracker_to_spreadsheet(self):
    """High-level function to migrate data from Tracker to the spreadsheet."""
    (t_issues, ss_issues) = self.fetch_issues()
    if len(ss_issues) == 0:
      raise Exception('Error: must have at least one non-header row in '\
                      'spreadsheet')
      return
    ss_keys = ss_issues[0].keys()

    print 'Calculating deltas...'
    ss_commits = self.tracker_to_spreadsheet_commits(t_issues, ss_issues)
    self.debug('commits: %s' % ss_commits)
    if not ss_commits:
      print 'Nothing to commit.'
      return
    print 'Committing...'
    for commit in ss_commits:
      self.debug('Operating on commit: %s' % commit)
      if commit['type'] == 'append':
        print 'Appending new row...'
        if not self.pretend:
          self.gd_client.InsertRow(commit['new_row'],
                                   self.ss_key, self.ss_ws_key)
        else:
          print '(Skipped because --pretend set)'
      if commit['type'] == 'update':
        print 'Updating row...'
        if not self.pretend:
          self.gd_client.UpdateRow(commit['__raw_entry'], commit['dict'])
        else:
          print '(Skipped because --pretend set)'
      print 'Done.'

def main():
  class PureEpilogOptionParser(OptionParser):
    def format_epilog(self, formatter):
      return self.epilog

  parser = PureEpilogOptionParser()
  parser.add_option('-a', '--action', dest='action', metavar='ACTION',
                    help='Action to perform')
  parser.add_option('-d', '--debug', action='store_true', dest='debug',
                    default=False, help='Print debug output.')
  parser.add_option('-m', '--message', dest='message', metavar='TEXT',
                    help='Log message when updating Tracker issues')
  parser.add_option('-p', '--pretend', action='store_true', dest='pretend',
                    default=False, help="Don't commit anything.")
  parser.add_option('--ss_key', dest='ss_key', metavar='KEY',
                    help='Spreadsheets key (find with browse action)')
  parser.add_option('--ss_ws_key', dest='ss_ws_key', metavar='KEY',
                    help='Spreadsheets worksheet key (find with browse action)')
  parser.add_option('--tracker_project', dest='tracker_project',
                    metavar='PROJECT',
                    help='Tracker project (default: chromium-os)',
                    default='chromium-os')
  parser.epilog = """Actions:
  browse -- browse spreadsheets to find spreadsheet and worksheet keys.
  ss_to_t -- for each entry in spreadsheet, apply its values to tracker.
             If no ID is in the spreadsheet row, a new tracker item is created
             and the spreadsheet is updated.
  t_to_ss -- for each tracker entry, apply it or add it to the spreadsheet.


This script can be used to migrate Issue Tracker issues between Issue Tracker
and Google Spreadsheets. The spreadsheet should have certain columns in any
order: Id, Owner, Title, Status. The spreadsheet may have any label of the
form 'Key-'. For those labels that end in '-', this script assumes the cell
value and the header form a label that should be applied to the issue. E.g.
if the spredsheet has a column named 'Mstone-' and a cell under it called
'R8' that corresponds to the label 'Mstone-R8' in Issue Tracker.

To migrate data, you must choose on each invocation of this script if you
wish to migrate data from Issue Tracker to a spreadsheet of vice-versa.

When migrating from Tracker, all found issues based on the query
(which is currently hard-coded to "label=Area-Installer") will be inserted
into the spreadsheet (overwritng existing cells if a row with matching ID
is found). Custom columns in the spreadsheet won't be overwritten, so if
the spreadsheet contains extra columns about issues (e.g. time estimates)
they will be preserved.

When migrating from spreadsheet to Tracker, each row in the spreadsheet
is compared to existing tracker issues that match the query
(which is currently hard-coded to "label=Area-Installer"). If the
spreadsheet row has no Id, a new Issue Tracker issue is created and the new
Id is written back to the spreadsheet. If an existing tracker issue exists,
it's updated with the data from the spreadsheet if anything has changed.

Suggested usage:
- Create a spreadsheet with columns Id, Owner, Title, Status, and any label
prefixes as desired.
- Run this script with '-b' to browse your spreadsheet and get the
spreadsheet key.
- Run this script again with '-b' and the spreadsheet key to get the
worksheet key.
- Run this script with "-a t_to_ss" or "-a ss_to_t" to migrate data in either
direction.

Known issues:
- query is currently hardcoded to label=Area-Installer. That should be
a command-line flag.
- When creating a new issue on tracker, the owner field isn't set. I (adlr)
am not sure why. Workaround: If you rerun this script, tho, it will detect
a delta and update the tracker issue with the owner, which seems to succeed.
"""

  (options, args) = parser.parse_args()

  merger = Merger(options.ss_key, options.ss_ws_key,
                  options.message, options.tracker_project,
                  options.debug, options.pretend)
  if options.action == 'browse':
    merger.browse()
  elif options.action == 'ss_to_t':
    if not options.message:
      print 'Error: when updating tracker, -m MESSAGE required.'
      return
    merger.spreadsheet_to_tracker()
  elif options.action == 't_to_ss':
    merger.tracker_to_spreadsheet()
  else:
    raise Exception('Unknown action requested.')

if __name__ == '__main__':
  main()
