r"""
module fileinfo - find out information about files and compare it.

It contains class FileInfo.
"""

import os, stat, time, pwd, grp

__all__=['FileInfo']

class FileInfo:
    r"""Class, which finds information about files and compares them.

    Informations like type of file, access rights, UID, GID, owner,
    group, size, last modification time and last access time for each file are found out.
    These information are compared and then are showed in ndiff output format.
    """
    def __init__(self,file1_name=None, file2_name=None,param=None):
        r"""Constructs FileInfo instance.

        parameters:
        file1_name - name of the first file
        file2_name - name of the second file
        param - options from optparse

        instance variables:
        self.file1_name - name of the first file
        self.file2_name - name of the second file
        """
        self.file1_name=file1_name
        self.file2_name=file2_name
        self.param=param

    def get_fileinfo(self,file_name):
        r"""return fileinfo

        This method reads file information and returns list of tuples:
        ("Name:",name),("Type:",type),("Owner:",owner),("UID:",uid),
        ("Group:",group),("GID:",gid),("Perm.:",acces),("Size:",size),
        ("Access:",last_acces),("Modif.:",last_modification)
        """

        name=os.path.basename(file_name)

        statinfo=os.lstat(file_name)

        if stat.S_ISDIR   (statinfo.st_mode): type="directory"
        elif stat.S_ISCHR (statinfo.st_mode): type="character special"
        elif stat.S_ISBLK (statinfo.st_mode): type="block special"
        elif stat.S_ISREG (statinfo.st_mode): type="regular file"
        elif stat.S_ISFIFO(statinfo.st_mode): type="fifo"
        elif stat.S_ISLNK (statinfo.st_mode): type="symbolic link"
        elif stat.S_ISSOCK(statinfo.st_mode): type="socket"
        else: type="unknown"

        acces=""
        if stat.S_IRUSR & statinfo.st_mode : acces +='r'
        else:                                acces +='-'
        if stat.S_IWUSR & statinfo.st_mode : acces +='w'
        else:                                acces +='-'
        if stat.S_IXUSR & statinfo.st_mode : acces +='x'
        else:                                acces +='-'
        if stat.S_IRGRP & statinfo.st_mode : acces +='r'
        else:                                acces +='-'
        if stat.S_IWGRP & statinfo.st_mode : acces +='w'
        else:                                acces +='-'
        if stat.S_IXGRP & statinfo.st_mode : acces +='x'
        else:                                acces +='-'
        if stat.S_IROTH & statinfo.st_mode : acces +='r'
        else:                                acces +='-'
        if stat.S_IWOTH & statinfo.st_mode : acces +='w'
        else:                                acces +='-'
        if stat.S_IXOTH & statinfo.st_mode : acces +='x'
        else:                                acces +='-'


        uid=statinfo.st_uid
        gid=statinfo.st_gid

        owner=(pwd.getpwuid(uid)).pw_name
        group=(grp.getgrgid(gid)).gr_name

        size=str(statinfo.st_size)+'B'

        last_acces=time.ctime(statinfo.st_atime)
        last_modification=time.ctime(statinfo.st_mtime)

        return (("Name:",name),("Type:",type),("Owner:",owner),("UID:",uid),
                ("Group:",group),("GID:",gid),("Perm.:",acces),("Size:",size),
                ("Access:",last_acces),("Modif.:",last_modification))


    def compare_fileinfo(self):
        r"""Compares file information and returns result in ndiff output format."""
        file1_info = self.get_fileinfo(self.file1_name)
        file2_info = self.get_fileinfo(self.file2_name)
        result=""
        for x,y in zip(file1_info, file2_info):
            if x[1] == y[1]:
                if self.param.F:
                    yield ('  {0:7} {1:<25}\n'.format(x[0],x[1]))
            else:
                yield ('+ {0:7} {1:<25}\n'.format(y[0],y[1]))
                yield ('- {0:7} {1:<25}\n'.format(x[0],x[1]))
