#!/usr/bin/env python
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#

from qpidstore import jerr, jrnl, janal
import optparse, os, sys


#== class StoreChk ============================================================

class StoreChk(object):
    """
    This class:
     1. Reads a journal jinf file, and from its info:
     2. Analyzes the journal data files to determine which is the last to be written, then
     3. Reads and analyzes all the records in the journal files.
    The only public method is run() which kicks off the analysis.
    """
    
    def __init__(self):
        """Constructor"""
        # params
        self.opts = None
        
        self._jdir = None
        
        # recovery analysis objects
#        self._jrnl_info = None
#        self.jrnl_rdr = None
        
        self._process_args()
        self._jrnl_info = jrnl.JrnlInfo(self._jdir, self.opts.bfn)
        # FIXME: This is a hack... find an elegant way of getting the file size to jrec!
        jrnl.JRNL_FILE_SIZE = self._jrnl_info.get_jrnl_file_size_bytes()
        self.jrnl_anal = janal.JrnlAnalyzer(self._jrnl_info)
        self.jrnl_rdr = janal.JrnlReader(self._jrnl_info, self.jrnl_anal, self.opts.qflag, self.opts.rflag,
                                         self.opts.vflag)

    def run(self):
        """Run the store check"""
        if not self.opts.qflag:
            print self._jrnl_info
            print self.jrnl_anal
        self.jrnl_rdr.run()
        self._report()
        
    def _report(self):
        """Print the results of the store check"""
        if not self.opts.qflag:
            print
            print " === REPORT ===="
            print
            print "Records:      %8d non-transactional" % \
                  (self.jrnl_rdr.get_msg_cnt() - self.jrnl_rdr.get_txn_msg_cnt())
            print "              %8d transactional" % self.jrnl_rdr.get_txn_msg_cnt()
            print "              %8d total" % self.jrnl_rdr.get_msg_cnt()
            print
            print "Transactions: %8d aborts" % self.jrnl_rdr.get_abort_cnt()
            print "              %8d commits" % self.jrnl_rdr.get_commit_cnt()
            print "              %8d total" % (self.jrnl_rdr.get_abort_cnt() + self.jrnl_rdr.get_commit_cnt())
            print
            if self.jrnl_rdr.emap().size() > 0:
                print "Remaining enqueued records (sorted by rid): "
                rid_list = self.jrnl_rdr.emap().rids()
                rid_list.sort()
                for rid in rid_list:
                    l = self.jrnl_rdr.emap().get(rid)
                    locked = ""
                    if l[2]:
                        locked += " (locked)"
                    print "  fid=%d %s%s" % (l[0], l[1], locked)
                print "WARNING: Enqueue-Dequeue mismatch, %d enqueued records remain." % self.jrnl_rdr.emap().size()
            else:
                print "No remaining enqueued records found (emap empty)."
            print
            if self.jrnl_rdr.tmap().size() > 0:
                txn_rec_cnt = 0
                print "Incomplete transactions: "
                for xid in self.jrnl_rdr.tmap().xids():
                    jrnl.Utils.format_xid(xid)
                    recs = self.jrnl_rdr.tmap().get(xid)
                    for l in recs:
                        print "  fid=%d %s" % (l[0], l[1])
                    print " Total: %d records for %s" % (len(recs), jrnl.Utils.format_xid(xid))
                    print
                    txn_rec_cnt += len(recs)
                print "WARNING: Incomplete transactions found, %d xids remain containing a total of %d records." % \
                      (self.jrnl_rdr.tmap().size(), txn_rec_cnt)
            else:
                print "No incomplete transactions found (tmap empty)."
            print
            print "%d enqueues, %d journal records processed." % \
                  (self.jrnl_rdr.get_msg_cnt(), self.jrnl_rdr.get_rec_cnt())
    
        
    def _process_args(self):
        """Process the command-line arguments"""
        opt = optparse.OptionParser(usage="%prog [options] DIR", version="%prog 1.0")
        opt.add_option("-b", "--base-filename",
                      action="store", dest="bfn", default="JournalData",
                      help="Base filename for old journal files")
        opt.add_option("-q", "--quiet",
                      action="store_true", dest="qflag",
                      help="Quiet (suppress all non-error output)")
        opt.add_option("-r", "--records",
                      action="store_true", dest="rflag",
                      help="Print all records and transactions (including consumed/closed)")
        opt.add_option("-v", "--verbose",
                      action="store_true", dest="vflag",
                      help="Verbose output")
        (self.opts, args) = opt.parse_args()
        if len(args) == 0:
            opt.error("No journal directory argument")
        elif len(args) > 1:
            opt.error("Too many positional arguments: %s" % args)
        if self.opts.qflag and self.opts.rflag:
            opt.error("Quiet (-q/--quiet) and record (-r/--records) options are mutually exclusive")
        if self.opts.qflag and self.opts.vflag:
            opt.error("Quiet (-q/--quiet) and verbose (-v/--verbose) options are mutually exclusive")
        self._jdir = args[0]
        if not os.path.exists(self._jdir):
            opt.error("Journal path \"%s\" does not exist" % self._jdir)


#== class CsvStoreChk =========================================================

class CsvStoreChk(StoreChk):
    """
    This class, in addition to analyzing a journal, can compare the journal footprint (ie enqueued/dequeued/transaction
    record counts) to expected values from a CSV file. This can be used for additional automated testing, and is
    currently in use in the long store tests for journal encode testing.
    """
    
    # CSV file cols
    TEST_NUM_COL = 0
    NUM_MSGS_COL = 5
    MIN_MSG_SIZE_COL = 7
    MAX_MSG_SIZE_COL = 8
    MIN_XID_SIZE_COL = 9
    MAX_XID_SIZE_COL = 10
    AUTO_DEQ_COL = 11
    TRANSIENT_COL = 12
    EXTERN_COL = 13
    COMMENT_COL = 20
    
    def __init__(self):
        """Constructor"""
        StoreChk.__init__(self)

        # csv params
        self.num_msgs = None
        self.msg_len = None
        self.auto_deq = None
        self.xid_len = None
        self.transient = None
        self.extern = None
        
        self._warning = []
        
        self.jrnl_rdr.set_callbacks(self, CsvStoreChk._csv_pre_run_chk, CsvStoreChk._csv_enq_chk,
                                    CsvStoreChk._csv_deq_chk, CsvStoreChk._csv_txn_chk, CsvStoreChk._csv_post_run_chk)
        self._get_csv_test()

    def _get_csv_test(self):
        """Get a test from the CSV reader"""
        if self.opts.csvfn != None and self.opts.tnum != None:
            tparams = self._read_csv_file(self.opts.csvfn, self.opts.tnum)
            if tparams == None:
                print "ERROR: Test %d not found in CSV file \"%s\"" % (self.opts.tnum, self.opts.csvfn)
                sys.exit(1)
            self.num_msgs = tparams["num_msgs"]
            if tparams["min_size"] == tparams["max_size"]:
                self.msg_len = tparams["max_size"]
            else:
                self.msg_len = 0
            self.auto_deq = tparams["auto_deq"]
            if tparams["xid_min_size"] == tparams["xid_max_size"]:
                self.xid_len = tparams["xid_max_size"]
            else:
                self.xid_len = 0
            self.transient = tparams["transient"]
            self.extern = tparams["extern"]

    def _read_csv_file(self, filename, tnum):
        """Read the CSV test parameter file"""
        try:
            csvf = open(filename, "r")
        except IOError:
            print "ERROR: Unable to open CSV file \"%s\"" % filename
            sys.exit(1)
        for line in csvf:
            str_list = line.strip().split(",")
            if len(str_list[0]) > 0 and str_list[0][0] != "\"":
                try:
                    if (int(str_list[self.TEST_NUM_COL]) == tnum):
                        return { "num_msgs": int(str_list[self.NUM_MSGS_COL]),
                                 "min_size": int(str_list[self.MIN_MSG_SIZE_COL]),
                                 "max_size": int(str_list[self.MAX_MSG_SIZE_COL]),
                                 "auto_deq": not (str_list[self.AUTO_DEQ_COL] == "FALSE" or
                                                  str_list[self.AUTO_DEQ_COL] == "0"),
                                 "xid_min_size": int(str_list[self.MIN_XID_SIZE_COL]),
                                 "xid_max_size": int(str_list[self.MAX_XID_SIZE_COL]),
                                 "transient": not (str_list[self.TRANSIENT_COL] == "FALSE" or
                                                   str_list[self.TRANSIENT_COL] == "0"),
                                 "extern": not (str_list[self.EXTERN_COL] == "FALSE" or
                                                str_list[self.EXTERN_COL] == "0"),
                                 "comment": str_list[self.COMMENT_COL] }
                except Exception:
                    pass
        return None
        
    def _process_args(self):
        """Process command-line arguments"""
        opt = optparse.OptionParser(usage="%prog [options] DIR", version="%prog 1.0")
        opt.add_option("-b", "--base-filename",
                      action="store", dest="bfn", default="JournalData",
                      help="Base filename for old journal files")
        opt.add_option("-c", "--csv-filename",
                      action="store", dest="csvfn",
                      help="CSV filename containing test parameters")
        opt.add_option("-q", "--quiet",
                      action="store_true", dest="qflag",
                      help="Quiet (suppress all non-error output)")
        opt.add_option("-r", "--records",
                      action="store_true", dest="rflag",
                      help="Print all records and transactions (including consumed/closed)")
        opt.add_option("-t", "--test-num",
                      action="store", type="int", dest="tnum",
                      help="Test number from CSV file - only valid if CSV file named")
        opt.add_option("-v", "--verbose",
                      action="store_true", dest="vflag",
                      help="Verbose output")
        (self.opts, args) = opt.parse_args()
        if len(args) == 0:
            opt.error("No journal directory argument")
        elif len(args) > 1:
            opt.error("Too many positional arguments: %s" % args)
        if self.opts.qflag and self.opts.rflag:
            opt.error("Quiet (-q/--quiet) and record (-r/--records) options are mutually exclusive")
        if self.opts.qflag and self.opts.vflag:
            opt.error("Quiet (-q/--quiet) and verbose (-v/--verbose) options are mutually exclusive")
        self._jdir = args[0]
        if not os.path.exists(self._jdir):
            opt.error("Journal path \"%s\" does not exist" % self._jdir)
        
    # Callbacks for checking against CSV test parameters. Return False if ok, True to raise error.
    
    #@staticmethod
    def _csv_pre_run_chk(csv_store_chk):
        """Check performed before a test runs"""
        if csv_store_chk.num_msgs == None:
            return
        if csv_store_chk.jrnl_anal.is_empty() and csv_store_chk.num_msgs > 0:
            raise jerr.AllJrnlFilesEmptyCsvError(csv_store_chk.get_opts().tnum, csv_store_chk.num_msgs)
        return False
    _csv_pre_run_chk = staticmethod(_csv_pre_run_chk)
    
    #@staticmethod
    def _csv_enq_chk(csv_store_chk, hdr):
        """Check performed before each enqueue operation"""
        #if csv_store_chk.num_msgs == None: return
        # 
        if csv_store_chk.extern != None:
            if csv_store_chk.extern != hdr.extern:
                raise jerr.ExternFlagCsvError(csv_store_chk.opts.tnum, csv_store_chk.extern)
            if hdr.extern and hdr.data != None:
                raise jerr.ExternFlagWithDataCsvError(csv_store_chk.opts.tnum)
        if csv_store_chk.msg_len != None and csv_store_chk.msg_len > 0 and hdr.data != None and \
           len(hdr.data) != csv_store_chk.msg_len:
            raise jerr.MessageLengthCsvError(csv_store_chk.opts.tnum, csv_store_chk.msg_len, len(hdr.data))
        if csv_store_chk.xid_len != None and csv_store_chk.xid_len > 0 and len(hdr.xid) != csv_store_chk.xid_len:
            raise jerr.XidLengthCsvError(csv_store_chk.opts.tnum, csv_store_chk.xid_len, len(hdr.xid))
        if csv_store_chk.transient != None and hdr.transient != csv_store_chk.transient:
            raise jerr.TransactionCsvError(csv_store_chk.opts.tnum, csv_store_chk.transient)
        return False
    _csv_enq_chk = staticmethod(_csv_enq_chk)
    
    #@staticmethod
    def _csv_deq_chk(csv_store_chk, hdr):
        """Check performed before each dequeue operation"""
        if csv_store_chk.auto_deq != None and not csv_store_chk.auto_deq:
            raise jerr.JWarning("[CSV %d] WARNING: Dequeue record rid=%d found in non-dequeue test - ignoring." %
                                (csv_store_chk.opts.tnum, hdr.rid))
            #self._warning.append("[CSV %d] WARNING: Dequeue record rid=%d found in non-dequeue test - ignoring." %
            #                     (csv_store_chk.opts.tnum, hdr.rid))
        return False
    _csv_deq_chk = staticmethod(_csv_deq_chk)
    
    #@staticmethod
    def _csv_txn_chk(csv_store_chk, hdr):
        """Check performed before each transaction commit/abort"""
        return False
    _csv_txn_chk = staticmethod(_csv_txn_chk)

    #@staticmethod
    def _csv_post_run_chk(csv_store_chk):
        """Cehck performed after the completion of the test"""
        # Exclude this check if lastFileFlag is set - the count may be less than the number of msgs sent because
        # of journal overwriting
        if csv_store_chk.num_msgs != None and not csv_store_chk.jrnl_rdr.is_last_file() and \
           csv_store_chk.num_msgs != csv_store_chk.jrnl_rdr.get_msg_cnt():
            raise jerr.NumMsgsCsvError(csv_store_chk.opts.tnum, csv_store_chk.num_msgs,
                                       csv_store_chk.jrnl_rdr.get_msg_cnt())
        return False
    _csv_post_run_chk = staticmethod(_csv_post_run_chk)

#==============================================================================
# main program
#==============================================================================

if __name__ == "__main__":
    M = CsvStoreChk()
    try:
        M.run()
    except Exception, e:
        sys.exit(e)
