
import os
import shutil

import fileutil
from acquisition import Acquest
from FileSystem import FileSystem
from cppDoc import CppDoc
from VdnWeaver import VdnWeaver

ospath = os.path

class PackageDoc (Acquest):
    def __init__ (self, name, home = '.', members = None, **options):
        Acquest.__init__ (self)
        self.name = name
        self.home = home
        self.members = members
        # options
        self.wantIndex = None
        options2attributes (self, options)

    def loadInfo (self, sourceFS):
        try:
            pkgFile = fileutil.defaultExtension (self.name, 'pkg')
            data = sourceFS.subdir (self.home).open (pkgFile, 'r').read ()
        except IOError:
            pass
        else:
            self.PackageDoc = PackageDoc
            self.SourceDoc = SourceDoc
            exec data in self.__dict__

    def make (self, sourceFS, targetFS, unconditional = None):
        self.loadInfo (sourceFS)
        ok = 1
        sourceFS = sourceFS.subdir (self.home)
        targetFS = targetFS.subdir (self.home)
        # copy optional html
        htmlfile = sourceFS.search (self.name + '.html', self.name + '.htm')
        if htmlfile:
            if unconditional or requiresUpdate (sourceFS, htmlfile, targetFS, htmlfile):
                shutil.copy2 (sourceFS.absolute (htmlfile), targetFS.absolute (htmlfile))
        if self.wantIndex:
            self.weaver = VdnWeaver (self.name, targetFS.base,
                self.acquire ('root'))
        self.members = map (normalizeMember, self.members)
        apply (self.promoteContext, tuple (self.members))
        for member in self.members:
            ok = ok and member.make (sourceFS, targetFS, unconditional)
            if ok and self.wantIndex:
                self.weaver.save ()
        if self.wantIndex:
            self.weaver.genIndex ()
        return ok

def requiresUpdate (sourceFS, sourcename, targetFS, targetname):
    try:
        targetTime = targetFS.getmtime (targetname)
    except os.error, err:
        return 1
    sourceTime = sourceFS.getmtime (sourcename)
    return sourceTime > targetTime

stringType = type ('')

def normalizeMember (member):
    if type (member) == stringType:
        ext = fileutil.extension (member)
        if ext == '.pkg':
            result = PackageDoc (member)
        else:
            result = SourceDoc (member)
    else:
        result = member
    return result

def packageFromFile (fname, **options):
    dir, file = ospath.split (fname)
    packageName, ext = ospath.splitext (file)
    if not dir:
        dir = '.'
    package = PackageDoc (packageName, dir)
    options2attributes (package, options)
    return package

class SourceDoc (Acquest):
    def __init__ (self, name, **options):
        self.name = name
        options2attributes (self, options)

    def make (self, sourceFS, targetFS, unconditional = None):
        targetfile = fileutil.setExtension (self.name, 'html')
        ok = 1
        if unconditional or requiresUpdate (sourceFS, self.name, targetFS, targetfile):
            ext = fileutil.extension (self.name)
            documenter = _documenters [ext] ()
            self.promoteContext (documenter)
            ok = documenter.readSource (sourceFS.absolute (self.name))
            if ok:
                documenter.genHTML (targetFS.require (targetfile))
            else:
                self.acquire ('weaver').removeCurrentEntries ()
                print self.name, 'not ok'
        return ok

def options2attributes (obj, options):
    if options:
        for name, value in options.items ():
            setattr (obj, name, value)

_documenters = {
    '.h': CppDoc,
    '.hpp': CppDoc,
    }

