#coding:utf-8
import os
import sys
import time
import shutil
import datetime
import tempfile
import subprocess
import sunhpc.commands
class Command(sunhpc.commands.create.command):
    """
    Create a Sunhpc distribution. Use this distribution to install Sunhpc nodes.

    <param type='str' name='arch'>
    Default:local machine - The architecture of the distribution.
    </param>

    <param type='str' name='version'>
    The version of the distribution.The default is: value of the machine
    </param>

    <param type='str' name='rolls'>
    Specify an or more roll name. The default is: All Rolls
    </param>

    <param type='str' name='root'>
    The path prefix location of the rolls. The default is: /works/sunhpc/install
    </param>

    <param type='str' name='dist'>
    The directory name of the distribution. The default is: "sunhpc-dist"
    </param>

    <param type='bool' name='md5'>
    Calculate MD5SUM of all packages. The default is: 'yes'
    </param>

    <example cmd='create distro'>
    Create a distribution in the current directory.
    </example>
    """
    def getRolls(self):
        rolls = []
        self.db.execute('select name, version, arch, enabled from rolls where OS="linux" ')
        for n, v, a, e in self.db.fetchall():
            if e == 'yes':
                rolls.append([n, v, a, e])

        return rolls

    def addRolls(self, rolls):
        for roll_name, roll_vers, roll_arch, roll_enb in rolls:
            rows = self.db.search("""select * from rolls 
                    where name="%s" 
                    and version="%s" 
                    and arch="%s" 
                    and os="%s" """ % (
                    roll_name, roll_vers, roll_arch, self.os))
            if not rows:
                addRoll = """insert into rolls 
                    (name, version, arch, enabled, os) 
                    values("%s", "%s", "%s", "%s", "%s")
                """ % (roll_name, roll_vers, 
                roll_arch, roll_enb, self.os)
                self.db.execute(addRoll)

    def commandDist(self, dist, rolls):
        builder = sunhpc.core.build.DistributionBuilder(dist)
        builder.setRolls(rolls)
        builder.setQuiet(self.quiet)
        builder.setSiteProfiles(1)
        builder.setCalcMD5(self.md5)
        builder.setCommand(self)
        builder.build()
        return builder

    def run(self, param, args):

        '''
        lockfile = '/var/lock/sunhpc-dist'
        if os.path.exists(lockfile):
            self.msg("%s exists already.Waiting or remove the lockfile." % lockfile, 'a')
        os.system('touch %s' % lockfile)
        '''

        (arch, version, withrolls, root,
            calcmd5, quiet, dist) = self.fillParams([
                ('arch', self.arch),
                ('version', sunhpc.version),
                ('rolls', None),
                ('root', '/export/sunhpc/install'),
                ('md5', 'yes'),
                ('quiet', 'no'),
                ('dist', 'sunhpc-dist')
                ])

        rolls = []
        if withrolls == None:
            rolls = self.getRolls()
        else:
            for i in withrolls.split():
                rolls.append(i.split(',') + [ 'yes' ])

        self.md5   = self.str2bool(calcmd5)
        self.quiet = self.str2bool(quiet)

        mirror = sunhpc.core.dist.Mirror()
        mirror.setHost('rolls')
        mirror.setPath(root)
        mirror.setRoot(root)
        mirror.setArch(arch)

        mirrors = []
        mirrors.append(mirror)

        distro = sunhpc.core.dist.Distribution(mirrors, version)
        distro.setRoot(os.getcwd())

        old_umask = os.umask(0o022)
        try:
            #
            # build the new distro in a temporary directory.
            #
            tempdist = tempfile.mkdtemp(dir="")
            distro.setDist(tempdist)

            distro.setLocal('/usr/src/redhat')
            distro.setContrib(os.path.join(mirror.getRootPath(), 'contrib', version))
            builder = self.commandDist(distro, rolls)
            #
            # make sure everyone can traverse the rolls directories.
            #
            mirrors = distro.getMirrors()
            fullmirror = mirrors[0].getRollsPath()
            # modify all dirs mode 755
            os.system(r'find %s -type d ' % (fullmirror) + r'-exec chmod -R 0755 {} \;')

            if self.arch != arch and os.path.exists(dist):
                shutil.move(os.path.join(tempdist, arch), os.path.join(dist, arch))
                shutil.rmtree(tempdist)
            else:
                #
                # now move the previous distro into a temporary directory
                #
                prevdist = tempfile.mkdtemp(dir="")
                try:
                    shutil.move(dist, prevdist)
                except:
                    pass

                shutil.move(tempdist, dist)
                os.system('chmod 755 %s' % dist)

                try:
                    shutil.rmtree(prevdist)
                except:
                    pass

            #os.unlink(lockfile)
        finally:
            os.umask(old_umask)
            self.addRolls(rolls)
