#! /usr/bin/env python

"""Londiste launcher.
"""

import sys, os, os.path, optparse

import pkgloader
pkgloader.require('skytools', '3.0')

import skytools

# python 2.3 will try londiste.py first...
if os.path.exists(os.path.join(sys.path[0], 'londiste.py')) \
    and not os.path.isdir(os.path.join(sys.path[0], 'londiste')):
    del sys.path[0]

import londiste, pgq.cascade.admin

command_usage = pgq.cascade.admin.command_usage + """
Replication Daemon:
  worker                replay events to subscriber

Replication Administration:
  add-table TBL ...     add table to queue
  remove-table TBL ...  remove table from queue
  add-seq SEQ ...       add sequence to provider
  remove-seq SEQ ...    remove sequence from provider
  tables                show all tables on provider
  seqs                  show all sequences on provider
  missing               list tables subscriber has not yet attached to
  resync TBL ...        do full copy again

Replication Extra:
  check                 compare table structure on both sides
  fkeys                 print out fkey drop/create commands
  compare [TBL ...]     compare table contents on both sides
  repair [TBL ...]      repair data on subscriber
  execute [FILE ...]    execute SQL files on set

Internal Commands:
  copy                  copy table logic
"""

cmd_handlers = (
    (('create-root', 'create-branch', 'create-leaf', 'members', 'tag-dead', 'tag-alive',
      'change-provider', 'rename-node', 'status', 'pause', 'resume',
      'drop-node', 'takeover'), londiste.LondisteSetup),
    (('add-table', 'remove-table', 'add-seq', 'remove-seq', 'tables', 'seqs',
      'missing', 'resync', 'check', 'fkeys', 'execute'), londiste.LondisteSetup),
    (('worker', 'replay'), londiste.Replicator),
    (('compare',), londiste.Comparator),
    (('repair',), londiste.Repairer),
    (('copy',), londiste.CopyTable),
)

class Londiste(skytools.DBScript):
    def __init__(self, args):
        skytools.DBScript.__init__(self, 'londiste3', args)

        if len(self.args) < 2:
            print("need command")
            sys.exit(1)
        cmd = self.args[1]
        self.script = None
        for names, cls in cmd_handlers:
            if cmd in names:
                self.script = cls(args)
                break
        if not self.script:
            print("Unknown command '%s', use --help for help" % cmd)
            sys.exit(1)

    def start(self):
        self.script.start()

    def print_ini(self):
        """Let the Replicator print the default config."""
        londiste.Replicator(['--ini'])

    def init_optparse(self, parser=None):
        p = skytools.DBScript.init_optparse(self, parser)
        p.set_usage(command_usage.strip())

        g = optparse.OptionGroup(p, "options for cascading")
        g.add_option("--provider",
                help = "init: upstream node temp connect string")
        g.add_option("--target",
                help = "switchover: target node")
        g.add_option("--merge",
                help = "create-leaf: combined queue name")
        g.add_option("--dead", action = 'append',
                help = "cascade: assume node is dead")
        g.add_option("--dead-root", action = 'store_true',
                help = "takeover: old node was root")
        g.add_option("--dead-branch", action = 'store_true',
                help = "takeover: old node was branch")
        p.add_option_group(g)
        g = optparse.OptionGroup(p, "repair queue position")
        g.add_option("--rewind", action = "store_true",
                help = "change queue position according to destination")
        g.add_option("--reset", action = "store_true",
                help = "reset queue pos on destination side")
        p.add_option_group(g)

        g = optparse.OptionGroup(p, "options for add")
        g.add_option("--all", action="store_true",
                help = "add: include add possible tables")
        g.add_option("--force", action="store_true",
                help = "add: ignore table differences, repair: ignore lag")
        g.add_option("--expect-sync", action="store_true", dest="expect_sync",
                help = "add: no copy needed", default=False)
        g.add_option("--skip-truncate", action="store_true", dest="skip_truncate",
                help = "add: keep old data", default=False)
        g.add_option("--create", action="store_true",
                help = "add: create table/seq if not exist")
        g.add_option("--create-only",
                help = "add: create table/seq if not exist (seq,pkey,full,indexes,fkeys)")
        g.add_option("--trigger-arg", action="append",
                help="add: Custom trigger arg")
        g.add_option("--handler", action="append",
                help="add: Custom handler for table")
        g.add_option("--copy-condition", dest="copy_condition",
                help = "add: set WHERE expression for copy")
        p.add_option_group(g)

        return p

if __name__ == '__main__':
    script = Londiste(sys.argv[1:])
    script.start()

