#!/usr/bin/python3.6 -s
# GPL. (C) 2019 Paolo Patruno.

# This program 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. 
# 
# This program 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
# 

import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'rmap.settings'
from django.conf import settings

from django.core import management
import rmap.settings
import sys, optparse, rmap.daemon
from rmap import  __version__
from django.contrib.auth.hashers import make_password
from rmap.utils import nint
import json

def ctrl(cwd):
    p = optparse.OptionParser(usage="usage: %prog [options]",version="%prog "+__version__)
    p.add_option("--syncdb", action="store_true",dest="syncdb", help="initialize rmap DB (default %default)", default=False)
    p.add_option("--collectstatic", action="store_true",dest="collectstatic", help="Collect static files from multiple apps into a single path (default %default)", default=False)
    p.add_option("--changeuser", action="store_true",dest="changeuser", help="change user to the user in config file (default %default)", default=False)
    p.add_option("--dumpdata", action="store_true", help=\
                 "dump Data Base (default %default)", default=False)
    p.add_option("--loaddata", type="string",action="store", help=\
                 "restore Data Base (default %default)", default=None)
    p.add_option("--exportsha", action="store_true",dest="exportsha", help="export hashed user password to stdout", default=False)
    p.add_option("--exportmqttsha", action="store_true",dest="exportmqttsha", help="export mqtt (station) hashed password to stdout", default=False)
    p.add_option("--exportmqttpskkey", action="store_true",dest="exportmqttpskkey", help="export mqtt (station) psk key to stdout", default=False)
    p.add_option("--exportmqttacl", action="store_true",dest="exportmqttacl", help="export hashed mqtt acl (topic) to stdout", default=False)
    p.add_option('--rpc_mqtt_admin_fdownload_v4',action="store_true", help="firmware download request to admin RPC over MQTT for Stima V4")
    p.add_option('--username',  default=None, help="work on station managed by this username")
    p.add_option('--station_slug',  default=None, help="work on station defined by this slug")
    p.add_option('--purge_rpc',action="store_true", help="remove non active RPC (submitted, running and completed")
    p.add_option('--purge_rpc_completed',action="store_true", help="remove non active RPC and completed")

    (options, args) = p.parse_args()

    import django

    # go to share dir for virtualenv
    ve=os.getenv("VIRTUAL_ENV")
    if ve is not None:
        os.chdir(ve+"/share/rmap")

    django.setup()
    from rpc.models import Rpc

    if (not options.syncdb and\
        not options.collectstatic and\
        not options.dumpdata and\
        options.loaddata is None and\
        not options.exportsha and\
        not options.exportmqttsha and\
        not options.exportmqttpskkey and\
        not options.exportmqttacl and\
        not options.purge_rpc and\
        not options.purge_rpc_completed and\
        not options.rpc_mqtt_admin_fdownload_v4):
        p.print_help()
        raise optparse.OptionValueError("you have to set one of --syncdb --collectdb --dumpdata --loaddata --rpc_mqtt_admin_fdownload_v4 --purge_rpc* or one of the export options")


    if (options.changeuser):
        dae=rmap.daemon.Daemon()
        dae.switchuser(user=rmap.rmap_config.user,group=rmap.rmap_config.group,env=None)
        #os.chdir(cwd)

    if (options.syncdb):
        #management.call_command("migrate",no_initial_data=True,app_label="auth",migration_name="0001_initial" )
        #management.call_command("migrate",no_initial_data=True,app_label="admin",migration_name="0001_initial" )
        #management.call_command("migrate",no_initial_data=True )
        management.call_command("migrate")

        #from django.core.management import call_command
        #call_command("createsuperuser",username="rmap",email="rmap@rmap.cc",interactive=False) 
        ##management.call_command("changepassword","rmap" )

        #from django.contrib.auth.models import User
        #u = User.objects.get(username__exact='rmap')
        #print (u.username+":$7"+u.password[u.password.find("$"):])
        #print (u.username+":"+u.password)
        #u.save()

    if (options.exportsha):
        from django.contrib.auth.models import User
        for u in User.objects.all():
            #print (u.username+":$7"+u.password[u.password.find("$"):])
            print (u.username+":"+u.password)


    if (options.exportmqttsha):
        from django.contrib.auth.models import User
        from rmap.stations.models import StationMetadata
        for u in User.objects.all():
            for mystation in StationMetadata.objects.filter(user__username=u.username):
                if mystation.active:
                    for myboard in mystation.board_set.all():
                        if hasattr(myboard, 'transportmqtt'):
                            if ( myboard.active and myboard.transportmqtt.active):
                                myuser = myboard.transportmqtt.mqttuser
                                mypassword = myboard.transportmqtt.mqttpassword

                                if (mypassword):
                                    #fake salt is for do not change password file to optimize mosquitto reload
                                    #print(myuser+":"+make_password(mypassword,"fake-salt"))
                                    print(u.username+"/"+mystation.slug+"/"+myboard.slug+":"+make_password(mypassword,"fake-salt"))
                        
    if (options.exportmqttpskkey):
        from django.contrib.auth.models import User
        from rmap.stations.models import StationMetadata
        for u in User.objects.all():
            for mystation in StationMetadata.objects.filter(user__username=u.username):
                if mystation.active:
                    for myboard in mystation.board_set.all():
                        if hasattr(myboard, 'transportmqtt'):
                            if ( myboard.active and myboard.transportmqtt.active):
                                myuser = myboard.transportmqtt.mqttuser
                                mypskkey = myboard.transportmqtt.mqttpskkey
                            
                                if (mypskkey):
                                    #print(myuser+":"+mypskkey)
                                    #print(myuser+"/"+mystation.slug+"/"+myboard.slug+":"+mypskkey)
                                    print(u.username+"/"+mystation.slug+"/"+myboard.slug+":"+mypskkey)
                                    


    if (options.exportmqttacl):

        #print ("topic","read","#")
        #print ("topic","test/#")

        from django.contrib.auth.models import User
        from rmap.stations.models import StationMetadata
        lastusername=None
        for u in User.objects.all():
            username=u.username
            print("user", username)
            lastusername=username


            # admin patterns
            if u.is_superuser:
                print("topic #")
            
            # legacy V0 topics
            for network in ("fixed","mobile"):
                for prefix in (rmap.settings.topicsample,rmap.settings.topicreport,rmap.settings.topicmaint,"rpc"):
                    mytopic="topic {}/{}/+/{}/#".format(prefix,username,network)
                    print (mytopic)

            # read all V1 user's stations
            for prefix in (rmap.settings.topicsample,rmap.settings.topicreport,rmap.settings.topicmaint,"rpc"):
                mytopic="topic read 1/{}/{}/#".format(prefix,username)
                print (mytopic)
            
            
            # V1 patterns
            for mystation in StationMetadata.objects.filter(user__username=u.username):
                if mystation.active:
                    lat=mystation.lat
                    lon=mystation.lon

                    for myboard in mystation.board_set.all():
                        if hasattr(myboard, 'transportmqtt'):
                            if ( myboard.active and myboard.transportmqtt.active):
                                username = myboard.transportmqtt.mqttuser+"/"+mystation.slug+"/"+myboard.slug

                                if not lastusername == username: print("user", username)
                                lastusername=username
                            
                                if mystation.lat is None:
                                    postfix="%s/+/%s/#" % (myboard.transportmqtt.mqttuser,mystation.network)
                                else:
                                    postfix="/%d,%d/%s/#" % (nint(mystation.lon*100000),nint(mystation.lat*100000),mystation.network)                                

                                for prefix in (rmap.settings.topicsample,rmap.settings.topicreport,rmap.settings.topicmaint,"rpc"):
                                    mytopic="topic 1/{}/{}/{}".format(prefix,myboard.transportmqtt.mqttuser,postfix)
                                    print (mytopic)

                                
    if (options.collectstatic):
        management.call_command("collectstatic")

    if (options.dumpdata):
        management.call_command("dumpdata",use_natural_foreign_keys = True, use_natural_primary_keys = True, exclude=["sites","sessions","admin","contenttypes","auth.Permission"])

    if (options.loaddata is not None):
        print("loaddata",options.loaddata)
        management.call_command("loaddata",options.loaddata)

        
    if (options.rpc_mqtt_admin_fdownload_v4):
        from django.contrib.auth.models import User
        from rmap.stations.models import StationMetadata
        if (options.username):
            users=(User.objects.get(username=options.username),)
        else:
            users=User.objects.all()
        for u in users:

            if (options.station_slug):
                stationmetadatas=(StationMetadata.objects.filter(user__username=u.username,slug=options.station_slug),)
            else:
                stationmetadatas=StationMetadata.objects.filter(user__username=u.username,type="stimav4")
            
            for mystationmetadata in stationmetadatas:
                if mystationmetadata.active:
                    method="admin"
                    params=json.loads('{"fdownload": true}')
                    myrpc=Rpc(stationmetadata=mystationmetadata,method=method,params=params)
                    print (u.username,mystationmetadata.slug,"execute:",myrpc)
                    myrpc.save()


    if (options.purge_rpc):
        Rpc.objects.filter(active=False).delete()
    if (options.purge_rpc_completed):
        Rpc.objects.filter(active=False).exclude(dateres=None).delete()

        
if __name__ == '__main__':

    cwd=os.getcwd()

    sys.exit(ctrl(cwd))  # (this code was run as script)
