# Copyright (C) 2008 Libresoft Research Group
#
# This program 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.
#
# This program 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# Authors : Israel Herraiz <herraiz@gsyc.escet.urjc.es>

import os
import sys
import commands
import datetime
import md5
from mydatabase import MyDatabase

TAR_DIR = "/usr/ports/distfiles/"
BASE_DIR = "/home/herraiz/sources/freebsd/6.0-RELEASE/"

class MyApplication:

    def __init__(self,user=None,password=None,host=None,dbname=None,sourcedir = TAR_DIR,basedir = BASE_DIR):

        self.db = MyDatabase()
        self.db.user = user
        self.db.password = password
        self.db.host = host
        self.db.name = dbname

        self.db.connect()

        self.sourcedir = sourcedir
        self.basedir = basedir
        self.tardir = ''

        self.accepted_types = ['.tar.gz','.tar.bz2','.tgz','.tbz','.zip']
        
    def run(self):

        #self.checkDirs()
        
        i = 0
        total_errors = 0
        tar_errors = 0
        for root, dirs, files in os.walk(self.sourcedir):
            for name in files:
                filepath = os.path.join(root, name)

                tarname = filepath.split('/')[-1]
                self.tardir = self.basedir + tarname
                self.checkDirs(self.tardir)

                ext = self.checkFileType(filepath)
                # If the file type is not accepted, drop out file
                if not ext:
                    continue
                # If the file can not be uncompressed, drop out file
                if not self.uncompressFile(filepath,ext):
                    continue

                # Fix permissions if needed
                self.checkDirs(self.tardir)
                
                print "Measuring "+tarname
                # Obtain port names and section where this file is present
                portname_list, portsection_list = self.db.getNameSection(tarname)
                i += 1
                total_size,errors = self.measureDir(tarname,portname_list,portsection_list)

                total_errors += errors
                
                if total_size > 0:
                    if not self.db.updateProject(tarname,total_size):
                        proj_errors += 1
                        

                self.db.connection.commit()
                
        print str(i) + " projects measured"
        print str(total_errors) + " errors inserting files in database"
        print str(tar_errors) + " errors inserting ports in database"
        

    def checkDirs(self,mydir):
        if not os.path.exists(mydir):
            os.makedirs(mydir)

        for root, dirs, files in os.walk(mydir, topdown=True):
            for name in dirs:
                os.system('chmod a+rwx "'+os.path.join(root, name)+'"')
            for name in files:
                os.system('chmod a+rwx "'+os.path.join(root, name)+'"')


    def uncompressFile(self,filepath,ext):
        os.chdir(self.tardir)

        if ext == ".tar.gz" or ext == ".tgz":
            cmd = 'tar zxf '+filepath
        elif ext == ".tar.bz2" or ext == ".tbz":
            cmd = 'tar jxf '+filepath
        elif ext == '.zip':
            cmd = 'unzip -o -qq '+filepath
        else:
            return False

        os.system(cmd)
        os.system("chmod -R a+rx .")

        return True

    def measureDir(self, tarname,portname_list,portsection_list):

        cmd = 'sloccount --wide --details '+self.tardir
       
        output = commands.getoutput(cmd)

        output_lines = output.split('\n')
                
        total_size = 0
        errors = 0

        for line in output_lines:


            # If no tab, ignore line
            if line.find('\t') == -1:
                continue

            try:
                fields = line.split('\t')
                sloc = fields[0]
                lang = 'l_'+fields[1]
                filepath = fields[3]
                filemd5 = self.getMD5(filepath)
            except:
                continue
         
            total_size += int(sloc)

            print "  * Storing " + filepath + " of " + sloc + " SLOC (" + lang.lstrip('l_') + ")"

            num_of_ports = len(portname_list)

            for i in range(num_of_ports):
                portname = portname_list[i]
                portsection = portsection_list[i]
                
                properties_dict = {'tarfilename':tarname,
                                   'portname':portname,
                                   'portsection':portsection,
                                   'size':sloc,
                                   'lang':lang,
                                   'filepath':filepath,
                                   'filemd5':filemd5}
            
                if not self.db.insertFile(properties_dict):
                    errors += 1
            
        return total_size, errors
    
    def checkFileType(self,filepath):

        for ext in self.accepted_types:

            num_of_chars = -len(ext)

            if len(filepath) >= abs(num_of_chars):
                extfile = filepath[num_of_chars:]
              
                if ext == extfile:
                    return ext

        return False

    def getMD5(self,filepath):

        fileobj = open(filepath,'r')
        content = ''.join(fileobj.readlines())
        fileobj.close()

        md5hash = md5.new()
        md5hash.update(content)

        return md5hash.hexdigest()

    

        
if __name__ == '__main__':

    app = MyApplication('root','root','localhost','metrics_tse_herraiz')
    app.run()
