# -*- coding: utf-8 -*-
# Tabellio -- software suite for deliberative assemblies
#          -- suite logicielle pour assemblées délibératives
#          -- http://www.tabellio.org/
# Copyright (C) 2006 Parlement de la Communauté française de Belgique

# This file is part of Tabellio.

# Tabellio 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.

# Tabellio 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 this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

import os,re,string

def _isXml( bytes ):
    # Detect the encoding and check the XML signature which is
    # `<?xml '  (0x3c 0x3f 0x78 0x6d 0x6c 0x20)
    #

    # UTF8 without byte order mark
    if bytes.startswith( "\x3c\x3f\x78\x6d\x6c\x20" ):
        return 1
    # UTF8 with byte order mark
    if bytes.startswith( "\xef\xbb\xbf\x3c\x3f\x78\x6d\x6c\x20" ):
        return 1
    # UTF16_LE with byte order mark
    if bytes.startswith( "\xff\xfe\x3c\x00\x3f\x00\x78\x00\x6d\x00\x6c\x00\x20\x00" ):
        return 1
    # UTF16_LE without byte order mark
    if bytes.startswith( "\x3c\x00\x3f\x00\x78\x00\x6d\x00\x6c\x00\x20\x00" ):
        return 1
    # UTF16_BE with byte order mark
    if bytes.startswith( "\xfe\xff\x00\x3c\x00\x3f\x00\x78\x00\x6d\x00\x6c\x00\x20" ):
        return 1
    # UTF16_BE without byte order mark
    if bytes.startswith( "\x00\x3c\x00\x3f\x00\x78\x00\x6d\x00\x6c\x00\x20" ):
        return 1
    # UCS4_LE with byte order mark
    if bytes.startswith( "\xff\xfe\x00\x00\x3c\x00\x00\x00\x3f\x00\x00\x00\x78\x00" \
                         "\x00\x00\x6d\x00\x00\x00\x6c\x00\x00\x00\x20\x00\x00\x00" ):
        return 1
    # UCS4_LE without byte order mark
    if bytes.startswith( "\x3c\x00\x00\x00\x3f\x00\x00\x00\x78\x00\x00\x00" \
                         "\x6d\x00\x00\x00\x6c\x00\x00\x00\x20\x00\x00\x00" ):
        return 1
    # UCS4_BE with byte order mark
    if bytes.startswith( "\x00\x00\xfe\xff\x00\x00\x00\x3c\x00\x00\x00\x3f\x00\x00" \
                         "\x00\x78\x00\x00\x00\x6d\x00\x00\x00\x6c\x00\x00\x00\x20" ):
        return 1
    # UCS4_BE without byte order mark
    if bytes.startswith( "\x00\x00\x00\x3c\x00\x00\x00\x3f\x00\x00\x00\x78" \
                         "\x00\x00\x00\x6d\x00\x00\x00\x6c\x00\x00\x00\x20" ):
        return 1

    return 0

_formats = [
  ( "rtf",  "{\\rtf" ),
  ( "doc", "\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1\x00" ),
  ( "zip", "\x50\x4b\x03\x04" ),
  ( "xml", _isXml ),
  ( "pdf", re.compile("%PDF-[1234567890].[1234567890]").match ),
]

def fileFormat(data):
    if hasattr(data,"read"):
        pos = data.tell()
        s = data.read(256)
        data.seek(pos,0)
    else:
        s = data[:256]

    # Try the known formats
    for fmt, exp in _formats:
        if callable(exp):
            match = exp(s)
        else:
            match = s.startswith( exp )
        if match:
            return fmt

    return ""
