# -*- coding: UTF-8
#
# oonicli
# -------
# In here we take care of running ooniprobe from the command
# line interface
#
# :authors: Arturo Filastò, Isis Lovecruft
# :license: see included LICENSE file


import sys
import os
import random
import time

from twisted.internet import defer, reactor
from twisted.application import app
from twisted.python import usage, failure
from twisted.python.util import spewer

from ooni import nettest, runner, reporter, config

from ooni.inputunit import InputUnitFactory

from ooni.utils import net
from ooni.utils import checkForRoot, NotRootError
from ooni.utils import log

class Options(usage.Options, app.ReactorSelectionMixin):
    synopsis = """%s [options] [path to test].py
    """ % (os.path.basename(sys.argv[0]),)

    longdesc = ("ooniprobe loads and executes a suite or a set of suites of"
                " network tests. These are loaded from modules, packages and"
                " files listed on the command line")

    optFlags = [["help", "h"],
                ['debug-stacktraces', 'B',
                    'Report deferred creation and callback stack traces'],]

    optParameters = [["reportfile", "o", None, "report file name"],
                     ["collector", "c", None, 
                         "Address of the collector of test results. (example: http://127.0.0.1:8888)"],
                     ["logfile", "l", None, "log file name"],
                     ["pcapfile", "p", None, "pcap file name"]]

    compData = usage.Completions(
        extraActions=[usage.CompleteFiles(
                "*.py", descr="file | module | package | TestCase | testMethod",
                repeat=True)],)

    tracer = None

    def __init__(self):
        self['test'] = None
        usage.Options.__init__(self)

    def opt_asciilulz(self):
        from ooni.utils import logo
        print logo.getlogo()

    def opt_spew(self):
        """
        Print an insanely verbose log of everything that happens.  Useful
        when debugging freezes or locks in complex code.
        """
        sys.settrace(spewer)

    def parseArgs(self, *args):
        try:
            self['test'] = args[0]
            self['subArgs'] = args[1:]
        except:
            raise usage.UsageError("No test filename specified!")

def testsEnded(*arg, **kw):
    """
    You can place here all the post shutdown tasks.
    """
    log.debug("testsEnded: Finished running all tests")

def run():
    """
    Call me to begin testing from a file.
    """
    cmd_line_options = Options()
    if len(sys.argv) == 1:
        cmd_line_options.getUsage()
    try:
        cmd_line_options.parseOptions()
    except usage.UsageError, ue:
        raise SystemExit, "%s: %s" % (sys.argv[0], ue)

    if cmd_line_options['debug-stacktraces']:
        defer.setDebugging(True)

    log.start(cmd_line_options['logfile'])

    test_file_name = os.path.basename(cmd_line_options['test'])
    log.debug("Running script %s" % test_file_name)

    yamloo_filename, pcap_filename = config.oreport_filenames(test_file_name)

    if cmd_line_options['reportfile']:
        yamloo_filename = cmd_line_options['reportfile']
        pcap_filename = yamloo_filename+".pcap"

    if os.path.exists(yamloo_filename):
        log.msg("Report already exists with filename %s" % yamloo_filename)
        log.msg("Renaming it to %s" % yamloo_filename+'.old')
        os.rename(yamloo_filename, yamloo_filename+'.old')
    if os.path.exists(pcap_filename):
        log.msg("Report already exists with filename %s" % pcap_filename)
        log.msg("Renaming it to %s" % pcap_filename+'.old')
        os.rename(pcap_filename, pcap_filename+'.old')

    classes = runner.findTestClassesFromConfig(cmd_line_options)
    test_cases, options = runner.loadTestsAndOptions(classes, cmd_line_options)
    if config.privacy.includepcap:
        try:
            checkForRoot()
        except NotRootError:
            log.err("includepcap options requires root priviledges to run")
            log.err("you should run ooniprobe as root or disable the options in ooniprobe.conf")
            sys.exit(1)
        log.debug("Starting sniffer")
        sniffer_d = net.capturePackets(pcap_filename)

    tests_d = runner.runTestCases(test_cases, options,
            cmd_line_options, yamloo_filename)
    tests_d.addBoth(testsEnded)

    reactor.run()


@@ -2812,52 +2812,8 @@
 e)%0A%0A
-    log.start(cmd_line_options%5B'logfile'%5D)%0A%0A
     
@@ -2875,60 +2875,8 @@
 t'%5D)
-%0A    log.debug(%22Running script %25s%22 %25 test_file_name)
 %0A%0A  
@@ -3141,32 +3141,30 @@
 e):%0A        
-log.msg(
+print 
 %22Report alre
@@ -3201,33 +3201,32 @@
  yamloo_filename
-)
 %0A        log.msg
@@ -3214,32 +3214,30 @@
 ame%0A        
-log.msg(
+print 
 %22Renaming it
@@ -3260,33 +3260,32 @@
 _filename+'.old'
-)
 %0A        os.rena
@@ -3378,24 +3378,22 @@
     
-log.msg(
+print 
 %22Report 
 alre
@@ -3380,32 +3380,37 @@
   print %22Report 
+PCAP 
 already exists w
@@ -3437,25 +3437,24 @@
 cap_filename
-)
 %0A        log
@@ -3454,16 +3454,14 @@
     
-log.msg(
+print 
 %22Ren
@@ -3494,25 +3494,24 @@
 ename+'.old'
-)
 %0A        os.
@@ -3820,18 +3820,20 @@
     
-log.err(%22i
+print %22%5B!%5D I
 nclu
@@ -3880,17 +3880,16 @@
  to run%22
-)
 %0A       
@@ -3897,17 +3897,19 @@
     
-log.err(%22
+print %22    
 you 
@@ -3978,17 +3978,16 @@
 be.conf%22
-)
 %0A       
@@ -4011,26 +4011,22 @@
         
-log.debug(
+print 
 %22Startin
@@ -4035,17 +4035,16 @@
 sniffer%22
-)
 %0A       
@@ -4087,24 +4087,68 @@
 _filename)%0A%0A
+    log.start(cmd_line_options%5B'logfile'%5D)%0A%0A
     tests_d 

Make the logger start later to avoid having stdout prefixed with INFO:twisted * This makes the help messages of tests more readable and less clutterred