###############################################################################
#                                                                             #
#   Copyright 2005 University of Cambridge Computer Laboratory.               #
#                                                                             #
#   This file is part of Nprobe.                                              #
#                                                                             #
#   Nprobe 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.                                       #
#                                                                             #
#   Nprobe 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 Nprobe; if not, write to the Free Software                     #
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA #
#                                                                             #
###############################################################################


##############################################################################
## 
##
## Keep track of correlation between TCP modelled implementations and 
##  Client/Server implementations
##
## 

############################################################################ 

import string
from TCP_Imp import *
from nprobe import SERVER, CLIENT, intoa_string


############################################################################
############################################################################

class Atype:

    def __init__(self):
	
	self.ud = {}
	self.sd = {}
        self.hostdict = {}

#############################################################################

    def add(self, way, addr, atype, imp):

        if atype == None:
            atype = 'Unknown'

        if imp:
            imp = imp.descr()
        else:
            imp = None
	if way == SERVER:
	    dict = self.sd
	else:
	    dict = self.ud
	if not dict.has_key(atype):
	    dict[atype] = {imp:1}
	else:
	    d = dict[atype]
	    if not d.has_key(imp):
		d[imp] = 1
	    else:
		d[imp] += 1

        e = self.hostdict.setdefault((addr, way), {})
        if atype in e:
            e[atype] += 1
        else:
            e[atype] = 1

#############################################################################

    def printself(self):

        s = self.report_string()
        for l in s:
            print l

#############################################################################

    def printself_tofile(self, f):

        s = self.report_string()
        for l in s:
            f.write(l + '\n')

#############################################################################

    def printself_tolist(self, ls):

        s = self.report_string()
        for l in s:
            if len(l):
                ls.append(l)

#############################################################################

    def report_string(self):

        def by_addr(a, b):
            
            ssa = a[0][0]
            ssb = b[0][0]
            
            for m in [0xFF, 0xFF00, 0xFF0000, 0xFF0000]:
                sa = ssa & m
                sb = ssb & m
                if sa != sb:
                    return sa - sb
            return 0

        def by_1(a, b):
            return b[1] - a[1]

        s = []

	s.append('')

        for str, d in [
            ('User Agents and inferred TCP implementations: ', self.ud),
            ('Servers and inferred TCP implementations: ', self.sd)
                ]:
            s.append(str)

            atypes = d.items()
            atypes.sort()
            for a in atypes:
                s.append('  %s ' % (a[0]))
                imps = a[1].items()
                imps.sort()
                for i in imps:
                    imp = i[0]
                    #print imp
                    if imp:
                        s.append('    %s (%d) ' % (imp, i[1]))
                    else:
                        s.append('    Unknown (%d) ' % (i[1]))


        htypes = self.hostdict.items()
        htypes.sort(by_addr)
        for h in htypes:
            if h[0][1] == SERVER:
                s.append('%s: ' % (intoa_string(h[0][0])))
                at = h[1].items()
                at.sort(by_1)
                for a in at:
                    s.append('  %s (%d) ' % (a[0], a[1]))
	s.append(' ')

        return s

#############################################################################

    def write_logx(self, f, key1, key2):

	f.write('%%%% %s: User Agents and inferred TCP implementations:\n' % (key1))

	atypes = self.ud.items()
	atypes.sort()
	for a in atypes:
	    f.write('%% %s:  %s\n' % (key1, a[0]))
	    imps = a[1].items()
	    imps.sort()
	    for i in imps:
	       f.write('%% %s:    %s %d\n' % (key1, i[0], i[1]))

	f.write('%%%% %s: Servers and inferred TCP implementations:\n' % (key2))

	atypes = self.sd.items()
	atypes.sort()
	for a in atypes:
	    f.write('%% %s:  %s\n' % (key2, a[0]))
	    imps = a[1].items()
	    imps.sort()
	    for i in imps:
	       f.write('%% %s:    %s %d\n' % (key2, i[0], i[1]))

#############################################################################
