
# --------------------------------------------------------------------------------------------
# NOTE: This file is for instantiating the SERVER connection to Firebase and
# for making tokens for remote javascript clients.

# IMPORTANT CHECKLIST:  https://firebase.google.com/support/guides/launch-checklist?authuser=0
# --------------------------------------------------------------------------------------------

from django.http import HttpResponse
from django.conf import settings
from django.views.decorators.csrf import ensure_csrf_cookie
from django.contrib.auth.decorators import login_required
from firebase_admin import credentials, db, auth
import firebase_admin
import os 
import sys 
import pdb

# Sample Firebase security rules:
# {
  # "rules": {
    # "changeMessages": {
      # ".write":"auth.uid === 'ideatreeServer'",
      # ".read": "auth.uid === 'ideatreeServer'",
      # "$mapId": {
        # ".indexOn": ["time"],
        # ".read": "auth.uid === 'ideatreeUser'",
      # }
    # },
    # "chat": {
      # ".read": "auth.uid === 'ideatreeUser'",
      # ".write":"auth.uid === 'ideatreeUser'",
    # }
  # }
# }


__firebase = None 


def getFirebaseInstance():  # For Firebase SERVER Python Admin SDK 
  try:
    # FIXME write test for this
    if not settings.USE_FIREBASE:
      raise Warning("(Notice only): The client asked the server to instantiate Firebase, but Firebase has been turned off in the Django settings.")

    # See https://firebase.google.com/docs/database/admin/start
    # For background:  https://firebase.google.com/docs/auth/
    # Note: setting per-user security rules *for the server* won't work, since the server Admin is not considered a 'user' to Firebase.
    currentDir_path = os.path.dirname(os.path.realpath(__file__))
    if settings.USE_DEVEL_FIREBASE_SITE:
      # print-to-log method recommended by wsgi
      print("USING DEVEL Firebase Credentials",file=sys.stderr)
      cred = credentials.Certificate(settings.FIREBASE_DEVELOPMENT_SERVER_CREDENTIALS_PATH ) # Development real-time database
      # A service account login like this gets complete access by default, but we limit that with a custom value embedded in the auth object.  Must correspond
      # to the database rules on Firebase.
      firebaseAdmin = firebase_admin.initialize_app(cred, { 'databaseURL': 'https://ideatreetest.firebaseio.com', 'databaseAuthVariableOverride': {'uid':'ideatreeServer'}})
    else:
      # print-to-log method recommended by wsgi
      print("USING PRODUCTION Firebase Credentials",file=sys.stderr)
      cred = credentials.Certificate(settings.FIREBASE_PRODUCTION_SERVER_CREDENTIALS_PATH) # Production real-time database
      # A service account login like this gets complete access by default, but we limit that with a custom value embedded in the auth object.  Must correspond
      # to the database rules on Firebase.
      firebaseAdmin = firebase_admin.initialize_app(cred, { 'databaseURL': 'https://ideatree.firebaseio.com', 'databaseAuthVariableOverride': {'uid':'ideatreeServer'}})

    if firebaseAdmin: 
      return(firebaseAdmin)
    else:
      raise Warning("(Notice only): The cloud component that does real-time updates to others sharing this map is not reachable.  Try reloading the page to re-establish a connection.")
  except:
    raise



@ensure_csrf_cookie 
@login_required()
# The javascript client calls this (via an ajax post), and gets a custom token to authenticate the client.
# NOTE: It's important to understand the various kinds of tokens that Firebase uses.
def firebaseClientToken(request):
  try:
    # FIXME write test for this
    if not settings.USE_FIREBASE:
      raise Warning("(Notice only): The client asked the server for a Firebase token, but Firebase has been turned off in the Django settings.")

    global __firebase
    if __firebase is None:
      __firebase = getFirebaseInstance()  # get a SERVER instance in order to generate a CLIENT token

    # See https://firebase.google.com/docs/auth/admin/create-custom-tokens
    # case sensitive, and must match the rules set on the Firebase RealTime Database site's console.
    uid = "ideatreetest" if settings.USE_DEVEL_FIREBASE_SITE else "ideatreeUser"
    additional_claims = { } 
    token = auth.create_custom_token(uid,additional_claims) 
    return HttpResponse(token)
  except Exception as err:
    return HttpResponse("System error:" + str(err), status=406)



def push_value(rootAddr, childAddr, data):
  try:
    global __firebase
    if __firebase is None:
      __firebase = getFirebaseInstance()

    ref = db.reference(rootAddr)
    posts_ref = ref.child(childAddr)
    # IMPORTANT: the firebase docs say you can do a push() followed by a set(data).  Not true for the Python Firebase Admin!
    new_post_ref = posts_ref.push(data)
  except Exception:
    raise 


