# -*- coding: utf-8 -*-
import logging, os, re
import mv_common
import glob
from urllib2 import Request, urlopen, URLError, HTTPError
#client side
#CentralNFSallhosts=

def setup_nfs_client(systemconfig,data_config):
    nfslist=[]
    nfsmap_serverfile ="nfsmap"
    logging.info("____Start of setup_nfs__client____")
    scrubnfs(systemconfig.get("TEMPLATES"))

    if systemconfig.get("HaveCentralNFS") == "yes":
        logging.debug("    Using a Central NFS server")
        logging.debug("    NFSserver:%s" %systemconfig.get("NFSserver"))
        if systemconfig.get("NFSserver") == "file:nfsmap":
        #if it's a file check for it, failure results in downloading attempt from MBE
            nfsmap_file=data_config.MYTHHOME+"/templates/nfsmap"
            if not os.path.exists(nfsmap_file):
                logging.debug("    Couldn't find local %s",nfsmap_file)
                logging.info("    Trying to download nfsmap from MBE")
                nfsmap_file = download_nfsmap(systemconfig.get("dbhost"),nfsmap_serverfile)
            nfslist = process_nfsmap_file(nfsmap_file)

        #check for other filesname:

        elif re.search("^file:",systemconfig.get("NFSserver")):
            filename=systemconfig.get("NFSserver").split(":")[1]
            nfsmap_file=data_config.MYTHHOME+"/templates/"+filename
            nfslist = process_nfsmap_file(nfsmap_file)

        # if it's an ip  parse ip and download file
        elif re.search(":nfsmap$",systemconfig.get("NFSserver")):
            ip=systemconfig.get("NFSserver").split(":")[0]
            nfsmap_file = download_nfsmap(ip,nfsmap_serverfile)
            nfslist = process_nfsmap_file(nfsmap_file)
        #else treat it as a single mount point
        else:
            item = (systemconfig.get("NFSserver") , systemconfig["NFSmount"])
            nfslist.append(item)
    else:
        #if frontend_only or slave try to use MBE  nfs_map_auto
        if systemconfig.get("SystemType") == "Frontend_only" or systemconfig["SystemType"] == "Slave_backend":
            logging.info("     Central NFS not found, trying to use MBE as nfs server")
            nfsmap_serverfile = "nfsmap_auto"
            ip=systemconfig.get("dbhost")
            nfsmap_file = download_nfsmap(ip,nfsmap_serverfile)
            nfslist = process_nfsmap_file(nfsmap_file)


    setup_nfs_fstab(nfslist,data_config)
    logging.info("__End of nfs\n")
    return nfslist


def process_nfsmap_file(mapfile):
    logging.debug("   processing nfsmap file %s",mapfile)
    nfslist = []
    try:
        f = open(mapfile,"r")
        for line in f.readlines():
            if line.startswith("#"):
                continue
            item = line.split()
            if len(item) <= 1 :
                continue
            logging.debug("    %s",item)
            nfslist.append(item)
    except :
        logging.critical("Couldn't read file %s, or some other error",mapfile)
    return nfslist

def scrubnfs(templates):
    logging.info("    Scrubbing nfs")
    mv_common.cp_and_log("/etc/fstab",templates+"/fstab.conf.template")
    #used this sed cmd because it's clean and took me forever to figure out =)
    cmd='''sed '/^#STARTSCRUB.*$/,/^#ENDSCRUB.*$/d' %s/fstab.conf.template > /etc/fstab''' %templates
    mv_common.runcmd(cmd)

def download_nfsmap(ip,nfsmap_serverfile):
    nfsmap_file="/tmp/nfsmap"
    myurl="http://%s:1337/templates/%s" %(ip,nfsmap_serverfile)
    req = Request(myurl)

    try:
        f = urlopen(req)
        logging.info("    downloading %s", myurl)
        local_file = open(nfsmap_file, "w")
        #Write to our local file
        local_file.write(f.read())
        local_file.close()
    #handle errors
    except HTTPError, e:
        logging.info("    File download failed")
        logging.debug("    %s", myurl)
        logging.debug("   HTTP Error: %s", e.code)
    except URLError, e:
        logging.info("    File download failed")
        logging.debug("   %s",myurl)
        logging.debug("   URL Error: %s ", e.reason)

    return nfsmap_file

def setup_nfs_mkdir(nfs_dirname):
    logging.info("    Creating NFS mount point %s" , nfs_dirname)
    try:
        os.makedirs(nfs_dirname)
    except:
        logging.debug("   Failed creating  nfs mount point")





def setup_nfs_fstab(nfslist,data_config):
    logging.info("    Adding nfs paths to fstab")
    nfs_options =  mythhome = data_config.nfs_options
    try:
        f = open('/etc/fstab', 'a')
        line = "#STARTSCRUB --------------anything in this block will be scrubbed\n"
        f.write(line)
        for s, m in nfslist:
            line = "%s %s   nfs %s \n" %(s,m,nfs_options)
            setup_nfs_mkdir(m)
            logging.debug("    %s",line)
            f.write(line)
        line = "#ENDSCRUB\n"
        f.write(line)
        f.close()

        for s, m in nfslist:
            logging.info("    nfs mounting %s",m)
            cmd = ['mount',m]
            mv_common.runcmd_bg(cmd)


    except:
        logging.critical("    *Couldn't open /etc/fstab for writing")
    logging.debug("   Done adding nfs paths to fstab")





#server side
def setup_samba(systemconfig,data_config):
    mythhome = data_config.MYTHHOME
    excludes = data_config.share_exclude_dir
    if systemconfig.get("UseSamba") == "1":
        logging.info("    Activating windows file sharing")
        usersamba=mythhome+"/templates/smb.conf"
        mv_common.pacinstall("samba")
        if not os.path.exists("/etc/samba"):
            logging.debug("    Creating directory /etc/samba")
            try:
                os.makedirs("/etc/samba")
            except:
                pass

        if os.path.exists(usersamba):
            logging.debug("    Using user provided config file %s",usersamba)
            cmd = "install -D -m755  %s /etc/samba/smb.conf" %usersamba
            mv_common.runcmd(cmd)
        else:
            Samba_media = systemconfig.get("Samba_media")
            Samba_home = systemconfig.get("Samba_home")
            if systemconfig.get("Samba_mediareadonly") == "0":
                smreadonly = "yes"
            else:
                smreadonly = "no"

            if systemconfig.get("Samba_homereadonly") == "0":
                shreadonly = "yes"
            else:
                shreadonly = "no"
            domain = systemconfig.get("Samba_domain")
            servername = systemconfig.get("hostname")

            try:
                f = open(systemconfig.get("TEMPLATES")+"/samba/smb.conf.template",'r')
                t_smbconf = f.readlines()
                f.close()
            except:
                logging.info("   Couldn't open samba template file")
                return

            try:
                f = open("/etc/samba/smb.conf",'w')
            except:
                logging.info("   Couldn't open samba file")
                return

            for line in t_smbconf:
                outline = line
                if re.match("^.*workgroup", line):
                    logging.debug("    Setting workgroup to %s",domain)
                    outline="   workgroup = %s\n" %domain
                    logging.debug("     %s",outline)
                if re.match("^.* server string",line):
                    logging.debug("    Setting server name to %s",servername)
                    outline="   server string = %s\n" %servername
                    logging.debug("     %s",outline)
                f.write(outline)

            outline="include =  %s/templates/user.shares \n" %mythhome
            f.write(outline)
            if Samba_media == "1":
                outline="include =  /etc/samba/smb.conf.media\n"
                f.write(outline)
            if Samba_home == "1":
                outline="include =  /etc/samba/smb.conf.home\n"
                f.write(outline)
            f.close()

            logging.info("    Writing smb.conf.media")
            try:
                f = open("/etc/samba/smb.conf.media","w")
            except:
                logging.info("*   Couldn't open smb.conf.media")
                return

            shares = scan_for_shares()
            medialines='''
[%s]
    path = %s
    public = yes
    only guest = yes
    writeable  = %s
    printable = no
    force user = mythtv
    force group = mythtv
    create mask = 0755\n'''
            new_share=[]
            excludes
            for share in shares:
                share_name = share.split("/")[-1]
                share_path = share
                #new_share.append(medialines %(share_name,share_patch,smreadonly)
                f.write(medialines %(share_name,share_path,smreadonly) )
                logging.debug("     %s",medialines %(share_name,share_path,smreadonly) )
                excludeline = '    veto files = '
                for exclude in excludes:
                    excludeline+= ''' "/%s/" ''' %exclude

                if excludes != []:
                    f.write( excludeline)
                    logging.debug(excludeline)
                    f.write("\n")

            f.close()
            logging.info("    Writing smb.conf.home")
            try:
                    f = open("/etc/samba/smb.conf.home","w")
            except:
                logging.info("    Couldn't open smb.conf.home")
                return
            homelines='''
[home]
path = %s
public = yes
only guest = yes
writeable  = %s
printable = no
force user = mythtv
force group = mythtv
create mask = 0755 ''' %(data_config.MYTHHOME,shreadonly)
            f.write(homelines)
            f.close()
            logging.debug("     %s",homelines)

        logging.info("    Creating samba user mythtv")
        cmd = "(echo mythtv; echo mythtv) | smbpasswd -a mythtv"
        mv_common.runcmd(cmd)
        mv_common.add_service("nmbd")
        mv_common.add_service("smbd")
        mv_common.restart_service("nmbd")
        mv_common.restart_service("smbd")

    else:
        logging.info("    Removing windows file sharing")
        mv_common.remove_service("smbd")
        mv_common.remove_service("nmbd")
        mv_common.pacremove("samba")
        mv_common.pacinstall("smbclient")
    return

def scan_for_shares():
    import ConfigParser
    config = ConfigParser.RawConfigParser()
    file_list=glob.glob("/etc/storage.d/*.conf")
    share_list = []
    for conf_file in file_list:
        try:
            logging.debug("    mv_fileshare: reading in %s" %conf_file)
            config.read(conf_file)
            shareable = config.get('storage','shareable')
            if shareable == "True" :
                mp = config.get('storage','mountpoint')
                share_list.append(mp)
                if config.get('storage','mmount') == "True" :
                    share_list.append("/myth")
        except:
            logging.debug("    mv_fileshare: Couldn't open %s for reading" %conf_file)

    return share_list

def setup_etc_exports(shares,data_config,servername,nfslist):
    #read in /etc/ exports
    conf_file="/etc/exports"
    excludes = data_config.share_exclude_dir
    nfsmap_sg_auto_skip = data_config.SG_MAP_AUTONFS_SKIP
    nfsmap_auto_skip = data_config.MAP_AUTONFS_SKIP

    #print nfsmap_auto_skip
    nfs_auto_line ="%s:%s %s"
    nfs_map_auto = []
    share_list = []

    #populate nfs_map_auto with nfs_list.  nfs_list is populated from the
    #central nfs options
    #nfslist looks like  [('silverraid:/raid0/data/media', '/data/storage/nfs/silverraid')]
    for i in nfslist:
        sharename = i[0]
        mountpoint = i[1]
        templine = "%s %s" %(sharename,mountpoint)
        nfs_map_auto.append(templine)

    #create the lists for both /etc/exports and nfs_map_auto
    for share in shares:
        if share == "/myth":
            continue
        os.chdir(share)
        file_list=glob.glob("*")
        for dirname in file_list:
            if os.path.isdir(dirname):
                tempname = "%s/%s" %(share,dirname)
                if dirname not in nfsmap_auto_skip:
                    share_list.append(tempname)
                    if dirname not in nfsmap_sg_auto_skip:
                        templine = nfs_auto_line %(servername,tempname,tempname)
                        nfs_map_auto.append(templine)


        file_list=glob.glob("media/*")
        for dirname in file_list:
            if os.path.isdir(dirname):
                tempname = "%s/%s" %(share,dirname)
                if dirname not in nfsmap_auto_skip:
                    share_list.append(tempname)
                    if dirname not in nfsmap_sg_auto_skip:
                        templine = nfs_auto_line %(servername,tempname,tempname)
                        nfs_map_auto.append(templine)

    #read in users templates/nfs.shares
    logging.debug("   processing nfs.shares file")
    nfsshares_file=data_config.MYTHHOME+"/templates/nfs.shares"
    try:
        f = open(nfsshares_file,"r")
        for line in f.read().splitlines():
            if line.startswith("#"):
                continue
            item = line.split()
            if len(line) <= 1 :
                continue
            logging.debug("    %s",line)
            share_list.append(line)
    except :
        logging.critical("    Couldn't read %s",nfsshares_file)

    new_exports=[]
    new_exports.append("#This file was generated by systemconfig.py -m fileshare")
    new_exports.append("#Use exportfs -arv to reread. \n\n")
    #for exclude in excludes:
    #    share_line='''/%s   *(noaccess)''' %exclude
    #    new_exports.append(share_line)

    for share in share_list:
        share_line='''%s   *(rw,all_squash,anonuid=1000,anongid=1000,no_subtree_check)''' %share
        new_exports.append(share_line)
        #for exclude in excludes:
            #share_line='''/%s   *(noaccess)''' %exclude
            #new_exports.append(share_line)

    #write out nfs_map_auto
    try:

        logging.info("    writing nfsmap_auto")
        try:
            dirname ="%s/templates/" %data_config.MYTHHOME
            os.makedirs(dirname)
            cmd =  "chmod 755 %s" %dirname
            mv_common.runcmd(cmd)
            cmd =  "chown mythtv:users %s" %dirname
            mv_common.runcmd(cmd)
        except:
            pass
        try:
            cmd =  "chmod 755 %s" %dirname
            mv_common.runcmd(cmd)
            cmd =  "chown mythtv:users %s" %dirname
            mv_common.runcmd(cmd)
        except:
            pass
        conf_file_nfs = "%s/templates/nfsmap_auto" %(data_config.MYTHHOME)
        f=open(conf_file_nfs,'w')
        for line in nfs_map_auto:
            f.write(line)
            f.write("\n")
            logging.debug("%s" %line)
        f.close()
    except:
        logging.info("*   error writing %s" %conf_file_nfs)

    try:
        logging.info("    writing /etc/exports")
        f=open(conf_file,'w')
        for line in new_exports:
            f.write(line)
            f.write("\n")
            logging.debug("%s" %line)
        f.close()
    except:
        logging.info("*   error writing /etc/exports")



def setup_NFSshares(UseNFS,templatefile,data_config,servername,nfslist):
    if UseNFS == "1":
        logging.info("    Activating NFS server")
        mv_common.pacinstall("nfs-utils")
        mv_common.pacinstall("rpcbind")
        shares = scan_for_shares()
        setup_etc_exports(shares,data_config,servername,nfslist)
        mv_common.add_service("nfsd")
        mv_common.add_service("nfs-common")
        mv_common.add_service("rpcbind")
        cmd="exportfs -arv"
        mv_common.runcmd(cmd)
    else:
        logging.info("    Removing NFS server")
        mv_common.remove_service("nfsd")
        mv_common.remove_service("nfs-common")
    return

def setup_dyndns(DDnsEnable):
    if DDnsEnable == "1":
        logging.info("    Installing Dynamic DNS client")
        mv_common.pacinstall("inadyn")
        mv_common.add_service("inadyn")
    else:
        logging.info("    Removing Dynamic DNS client")
        mv_common.pacremove("inadyn")
        mv_common.remove_service("inadyn")


def setup_fileshare(systemconfig,data_config):
    if  mv_common.read_config(mv_common.module_config,"fileshare")  == False  :
        logging.info("____Skipping of fileshare, config disabled____")
        return
    logging.info("____Start of fileshare configuration____")

    #client, nfslist will be used in case the central NFS needs to also be addressed
    nfslist = setup_nfs_client(systemconfig,data_config)

    #server
    if systemconfig.get("CentralNFSallhosts") == "0":
        #reset nfslist to 0 so that central nfsshares do not get added to auto_nfs
        nfslist = []

    setup_NFSshares(systemconfig.get("UseNFS"),
                    systemconfig.get("TEMPLATES")+"/exports.template",
                    data_config,systemconfig.get("hostname"),
                    nfslist)

    setup_samba(systemconfig,data_config)

    logging.info("__End of fileshare configuration\n")
