from distutils.core import Command

class BuildIdl(Command):
    command_name = 'build_idl'

    description = "compile IDL file pstubs"

    user_options = [
        ('build-lib=', 'd', "directory to \"build\" (copy) to"),
        ('build-temp=', 't', 'directory for temporary files'),
        ('force', 'f', "forcibly build everything (ignore file timestamps)"),
        ]

    boolean_options = ['force']

    def initialize_options(self):
        self.build_lib = None
        self.build_temp = None
        self.force = 0
        self.idl_files = None
        self.outfiles = []
        return

    def finalize_options(self):
        self.set_undefined_options('build', ('build_lib', 'build_lib'),
                                            ('build_temp', 'build_temp'),
                                            ('force', 'force'))
        self.idl_files = self.distribution.idl_files
        self.build_temp = os.path.join(self.build_temp, 'idl')
        return

    def get_outputs(self):
        return self.outfiles

    def find_omniidl(self):
        omniidl = None
        try:
            import omniidl.main
            omniidl = omniidl.main.main
        except:
            if not find_executable('omniidl'):
                self.warn('unable to find omniidl, skipping IDL pstubs')
            else:
                omniidl = self.spawn
        return omniidl

    def run(self):
        if not self.idl_files:
            return

        idl_cmd = self.find_omniidl()
        if not idl_cmd:
            return
        
        self.outfiles = []
        for (package, idl_files) in self.idl_files:
            package_parts = package.split('.')

            temp_dir = [self.build_temp] + list(package_parts)
            temp_dir = apply(os.path.join, temp_dir)
            self.mkpath(temp_dir)

            for file in idl_files:
                build_file = os.path.join(temp_dir, os.path.basename(file))
                if not (self.force or newer(file, build_file)):
                    self.announce("skipping '%s' IDL pstubs (up-to-date)" % file)
                    continue

                # Create the pstubs
                self.announce("generating '%s' IDL pstubs" % file)
                args = ['omniidl', '-b', 'python', '-C', temp_dir, '-I', temp_dir, file]
                idl_cmd(args)

                # By coping after, we don't get skipped IDL files
                self.copy_file(file, build_file, preserve_mode=0)
            
            package_dir = [self.build_lib] + list(package_parts)
            package_dir = apply(os.path.join, package_dir)
            self.mkpath(package_dir)
            self.outfiles.extend(self.copy_tree(temp_dir, package_dir))

            # Ensure the package is really a module
            package_init = os.path.join(package_dir, '__init__.py')
            if not os.path.exists(package_init):
                self.announce("package '%s' __init__ not found, creating" % package)
                init = open(package_init, 'w')
                init.write('# Empty file to convince Python this is a module.\n')
                init.close()
                self.outfiles.append(package_init)

        return
