def updateSupplierItems(db, req_data):
    '''Updates a supplier entry with a new list of items selling'''
    sessionID = req_data['sessionID']
    itemNames = req_data['itemList']
    
    print(itemNames)
    
    userObject = data.getTableEntry(db, data.COLLECTION_USERS, {"sessionID": sessionID})
    if(userObject == []):
        return {"Status": "Failure: Invalid sessionID"}
    # user is valid 
    
    if(userObject[0]['role'] != "supplier"):
        return {"Status": "Failure: Not a supplier"}
    
    uname = userObject[0]['uname']
    
    supplierObject = data.getTableEntry(db, data.COLLECTION_SUPPLIERS, {"uname": uname})
    
    # update buying items entry with new array from req_data
    
    toUpdate = { "$set": { "selling": itemNames } }
    
    updateStatus = data.updateTableEntry(db, data.COLLECTION_SUPPLIERS, {"uname": uname}, toUpdate)
    
    if(updateStatus == None):
        return{"Status": "Failure: Could not update table entry for buyer"}
    else:
        return{"Status": "Success: Replaced buying list with new values"}
def updatePlotBill(db, req_data):
    sessionID = req_data['sessionID']
    billAmt = req_data['bill']
    landID = req_data['landID']
    plotID = req_data['plotID']

    ### verification
    # verify user exists
    userObject = data.getTableEntry(db, data.COLLECTION_USERS, {"sessionID": sessionID})
    if(userObject == []):
        return {"Status": "Failure: Invalid sessionID"} 
    # verify they are a landowner
    if(userObject[0]['role'] != 'landowner'):
        return {"Status": "Failure: Invalid user type"} 
    
    # get the specific plot info
    plotEntry = data.getTableEntry(db, data.COLLECTION_PLOTS, {"landID": landID, "plotID": plotID})
    
    if(plotEntry == []):
        return {"Status": "Failure: Invalid Plot Data"} 
    
    toUpdate = { "$set": { "price": billAmt } } 
    
    updateStatus = data.updateTableEntry(db, data.COLLECTION_PLOTS, {"landID": landID, "plotID": plotID}, toUpdate)
    
    if(updateStatus == None):
        return {"Status": "Failure: Could not update db"} 
    
    return {"Status": "Success: Updated DB"} 
def appendWaitingList(db, req_data):
    '''add a tenant to the waiting list of a plot'''
    sessionID = req_data['sessionID']
    plotID = req_data['plotID']
    landID = req_data['landID']
    
    userObject = data.getTableEntry(db, data.COLLECTION_USERS, {"sessionID": sessionID})
    if(userObject == []):
        return {"Status": "Failure: Invalid sessionID"}
    
    if(userObject[0]['role'] != "tenant"):
        return {"Status": "Failure: Invalid user role"}
    
    uname = userObject[0]['uname']
    identifier = {"landID": landID, "plotID": plotID}
    toUpdateObject = data.getTableEntry(db, data.COLLECTION_PLOTS, identifier)
    if(toUpdateObject == []):
        return {"Status": "Failure: Invalid plot identifier data"}
    
    waitingList = toUpdateObject[0]['waitingList']
    
    if(uname in waitingList):
        return {"Status": "You're already in the waiting list!"}
    
    waitingList.append(uname)
    
    documentToUpdate = { "$set": { "waitingList": waitingList } }
    
    status = data.updateTableEntry(db, data.COLLECTION_PLOTS, identifier, documentToUpdate)
    if(status == None):
        return {"Status": "Failure: Could not add to waiting list"}
    else:
        return {"Status": "Success: Added to waiting list"}
def updateUserInfo(db, sessionID, req_data):
    '''Updates a user contact info on the db given a valid sessionID and required fields'''
    # extract each element from req_data
    email = req_data['email']
    phoneNo = req_data['phoneNo']
    fName = req_data['fName']
    lName = req_data['lName']
    toUpdate = {
        "$set": {
            "email": email,
            "phoneNo": phoneNo,
            "fName": fName,
            "lName": lName
        }
    }
    # ensure sessionID is valid
    isValid = data.getTableEntry(db, data.COLLECTION_USERS,
                                 {"sessionID": sessionID})
    if (isValid == []):
        return {"Status": "Invalid Session ID!"}
    successStatus = data.updateTableEntry(db, data.COLLECTION_USERS,
                                          {"sessionID": sessionID}, toUpdate)
    if (successStatus == None):
        return {"Status": "Failure: Could not update user info"}

    return {"Status": "Success"}
def updatePassword(db, req_data):
    '''Update a user password given sessionID, current and new password'''
    sessionID = req_data['sessionID']
    currPwd = req_data['currentPassword']
    newPwd = req_data['newPassword']
    
    userObject = data.getTableEntry(db, data.COLLECTION_USERS, {"sessionID": sessionID})
    if(userObject == []):
        return {"Status": "Failure: Invalid Session ID"}
    
    currPwdHash = data.saltAndHash(currPwd)
    
    if(currPwdHash != userObject[0]['pwd']):
        return {"Status": "Failure: Password Does Not Match Database"}
    
    newPwdHash = data.saltAndHash(newPwd)
    toUpdate = { "$set": { "pwd": newPwdHash} }

    data.updateTableEntry(db, data.COLLECTION_USERS, {"sessionID": sessionID}, toUpdate)
    return {"Status": "Success: Password Updated!"}
def addLandEntry(db, req_data):
    '''Adds a land entry and associated plots to the database'''
    
    landID = req_data['landData']['landID']
    landFriendlyName = req_data['landData']['friendlyName']
    plotIDs = req_data['landData']['plotIDs']
    amenities = req_data['landData']['amenities']
    
    # check landID hasn't been taken already
    existingLand = data.getTableEntry(db, data.COLLECTION_LAND, {"landID": landID})
    if(existingLand != []):
        return {"Status": "Failure: LandID already taken"}
    
    # add landID to the landowner table
    sessionID = req_data['sessionID']
    userObject = data.getTableEntry(db, data.COLLECTION_USERS, {"sessionID": sessionID})
    if(userObject == []):
        return {"Status": "Failure: Invalid SessionID"}
    if(userObject[0]["role"] != "landowner"):
        return {"Status": "Failure: User is not a landowner"}
    
    existingLandownerLand = data.getTableEntry(db, data.COLLECTION_LANDOWNERS, {"uname": userObject[0]['uname']})[0]['landIDs']
    existingLandownerLand.append(landID)
    
    attemptedUpdate = data.updateTableEntry(db, data.COLLECTION_LANDOWNERS, {"uname": userObject[0]['uname']}, { "$set": { "landIDs": existingLandownerLand } })
    
    if(attemptedUpdate == None):
        return {"Status": "Failure: Cannot add landID to landowner entry"}
    
    
    # add land data to table entry
    document = {"landID": landID, "friendlyName": landFriendlyName, "plotIDs": plotIDs, "amenities": amenities}
    addedLand = data.createTableEntry(db, data.COLLECTION_LAND, document)
    
    if(addedLand == None):
        return {"Status": "Failure: Cannot add land entry to database"}
    
    for plot in plotIDs:
        # add each plot to the plot table, assuming no duplicate plotIDs in submitted collection
        landID = landID
        status = "Available"
        plotFriendlyName = ""
        plotPrice = req_data['plotData'][plot]['price']
        plotCoords = req_data['plotData'][plot]['coords']
        plotSize = req_data['plotData'][plot]['size']
        
        document = {"landID": landID, "plotID": plot, "status": status, "price": plotPrice, "friendlyName": plotFriendlyName,"waitingList": [], "coords": plotCoords, "size": plotSize}
        
        addedPlot = data.createTableEntry(db, data.COLLECTION_PLOTS, document)
        if(addedPlot == None):
            return {"Status": "Failure: Cannot add plot entry: " + plot + " to database"}
        
    return {"Status": "Success"}
def updateTenantItems(db, req_data):
    '''Updates the tenants produce entry on their specific plot'''
    sessionID = req_data['sessionID']
    plotID = req_data['plotID']
    landID = req_data['landID']
    produceArray = req_data['produce']
    
    ### verification
    # verify user exists
    userObject = data.getTableEntry(db, data.COLLECTION_USERS, {"sessionID": sessionID})
    if(userObject == []):
        return {"Status": "Failure: Invalid sessionID"} 
    # verify they are a tenant
    if(userObject[0]['role'] != 'tenant'):
        return {"Status": "Failure: Invalid user type"} 
    # verify they rent the plot
    tenantObject = data.getTableEntry(db, data.COLLECTION_TENANTS, {"uname": userObject[0]['uname']})
    if(tenantObject == []):
        return {"Status": "Failure: Invalid tenant data"}
    
    
    ### update produce with [[item, landID, plotID]]
    # get produce field
    tenantProduce = tenantObject[0]['produce']
    sendBack = []
    # for every entry, remove ones that match entry[1] == landID && entry[2] == plotID
    if(tenantProduce == [[]]):
        print("Not producing anything")
    else:
        print(tenantProduce)
        for entry in tenantProduce:
            print("LOOKING AT\n", entry)
            if(entry[1] == landID and entry[2] == plotID):
                print("Ignoring this item: ", entry)
            else:
                sendBack.append(entry)
            
    # for every element in produceArray, append produce field with [element, landID, plotID]
    for produce in produceArray:
        sendBack.append([produce, landID, plotID])
        print("ADDING ", produce)
    
    toUpdate = { "$set": { "produce": sendBack } }
    updateStatus = data.updateTableEntry(db, data.COLLECTION_TENANTS, {"uname": userObject[0]['uname']}, toUpdate)
    
    if(updateStatus == None):
        return {"Status": "Failure: Could not add to table"}
    
    return {"Status": "Success: Added to table"}
def giveNotice(db, req_data):
    '''Update the tenant entry with a notice field for a specified plot on land'''
    sessionID = req_data['sessionID']
    plotID = req_data['plotID']
    landID = req_data['landID']

    userObject = data.getTableEntry(db, data.COLLECTION_USERS,
                                    {"sessionID": sessionID})

    if (userObject == []):
        return {"Status": "Failure: Invalid sessionID"}

    tenancyData = data.getTableEntry(db, data.COLLECTION_TENANTS,
                                     {"uname": userObject[0]['uname']})

    if (tenancyData == []):
        return {"Status": "Failure: Invalid Tenant"}

    # see if plot already notice given

    plotNotice = tenancyData[0]['notice']

    for notice in plotNotice:
        if (plotID in notice and landID in notice):
            return {"Status": "Plot already noticed"}

    date = datetime.date.today()
    date = date + relativedelta(months=+6)
    noticeDateString = date

    tenantNotice = tenancyData[0]['notice']
    tenantNotice.append([plotID, landID, str(noticeDateString)])

    update = {"$set": {"notice": tenantNotice}}

    updateStatus = data.updateTableEntry(db, data.COLLECTION_TENANTS,
                                         {"uname": userObject[0]['uname']},
                                         update)
    if (updateStatus == None):
        return {"Status": "Failure: Something went wrong!"}
    else:
        return {"Status": "Success"}
def approveWaitingList(db, req_data):
    '''approve a tenant to start renting the plot from the waiting list'''
    sessionID = req_data['sessionID']
    
    plotID = req_data['plotID']
    landID = req_data['landID']

    approvedUname = req_data['uname']
    
    userObject = data.getTableEntry(db, data.COLLECTION_USERS, {"sessionID": sessionID})
    if(userObject == []):
        return {"Status": "Failure: Invalid sessionID"}
    
    if(userObject[0]['role'] != "landowner"):
        return {"Status": "Failure: Invalid user role"}
    
    uname = userObject[0]['uname']
#     check land belongs to the user associated with the landID!!
    landownerObject = data.getTableEntry(db, data.COLLECTION_LANDOWNERS, {"uname": uname})
    if(landownerObject == []):
        return {"Status": "Failure: Not a landowner!"}
    
    
    if(landID not in landownerObject[0]['landIDs']):
        return {"Status": "Failure: You dont own the land!"}
    
#     remove user from waiting list

    plotData = data.getTableEntry(db, data.COLLECTION_PLOTS, {"landID": landID, "plotID": plotID})
    if(plotData == []):
        return {"Status": "Failure: Invalid plot data"}
    
    waitingList = plotData[0]['waitingList']
    waitingList.remove(approvedUname)
    plotPrice = plotData[0]['price']
    
#     update new waitingList
    plotUpdate = { "$set": { "waitingList": waitingList, "status": "Unavailable" } }
    
    updatePlotStatus = data.updateTableEntry(db, data.COLLECTION_PLOTS, {"landID": landID, "plotID": plotID}, plotUpdate)
    
    # update tenants table with new plotID
    
    tenantObj = data.getTableEntry(db, data.COLLECTION_TENANTS, {"uname": approvedUname})
    
    if(tenantObj == []):
        return {"Status": "Failure: No tenant object found"}
    
    tenantPlots = tenantObj[0]["plots"]
    tenantBills = tenantObj[0]['totalBillAmt']
    tenantBillDates = tenantObj[0]['billDate']
    
    today = datetime.date.today()
    dateString = str(today.day) + "/" + str(today.month) + "/" + str(today.year)
    billDateString = str(today.day) + "/" + str(today.month)
    
    tenantPlots.append([landID, plotID, dateString])
    tenantBills += int(plotPrice)
    tenantBillDates.append([landID, plotID, billDateString])
    
    tenantIdentifier = {"uname": approvedUname}
    tenantUpdate = { "$set": { "plots": tenantPlots, "totalBillAmt": tenantBills, "billDate": tenantBillDates } }
    
    tenantUpdateStatus = data.updateTableEntry(db, data.COLLECTION_TENANTS, tenantIdentifier, tenantUpdate)
    
    if(tenantUpdateStatus == None):
        return {"Status": "Failure: Tenant table update stopped"}
    else:
        return {"Status": "Should be a success"}
    
    return None