```json
{
  "sym_variables": [
    ("x0", "CBRN platoons"),
    ("x1", "artillery batteries"),
    ("x2", "water purification units"),
    ("x3", "medical platoons")
  ],
  "objective_function": "4*x0**2 + 7*x0*x1 + 9*x0*x2 + 7*x0*x3 + 3*x1**2 + 2*x1*x2 + 8*x1*x3 + 5*x2*x3 + 5*x3**2 + 3*x0 + 1*x2",
  "constraints": [
    "3*x0 + 2*x1 + 5*x2 + 7*x3 <= 117",  // logistics footprint
    "6*x0 + 1*x1 + 6*x2 + 6*x3 <= 107",  // fun factor
    "5*x2 + 7*x3 >= 17",
    "(3*x0)**2 + (5*x2)**2 >= 23",
    "3*x0 + 2*x1 >= 11",
    "2*x1 + 5*x2 >= 19",
    "3*x0 + 2*x1 + 5*x2 + 7*x3 >= 19",
    "6*x0 + 1*x1 >= 14",
    "6*x2 + 6*x3 >= 20",
    "6*x0 + 1*x1 + 6*x2 + 6*x3 >= 20",
    "3*x0 + 2*x1 <= 106",
    "(2*x1)**2 + (7*x3)**2 <= 97",
    "(2*x1)**2 + (5*x2)**2 <= 59",
    "3*x0 + 5*x2 + 7*x3 <= 101"
  ]
}
```

```python
import gurobipy as gp

try:
    # Create a new model
    m = gp.Model("resource_allocation")

    # Create variables
    x = m.addVars(4, name=["CBRN", "Artillery", "Water", "Medical"], vtype=gp.GRB.INTEGER)

    # Set objective function
    m.setObjective(4*x[0]**2 + 7*x[0]*x[1] + 9*x[0]*x[2] + 7*x[0]*x[3] + 3*x[1]**2 + 2*x[1]*x[2] + 8*x[1]*x[3] + 5*x[2]*x[3] + 5*x[3]**2 + 3*x[0] + x[2], gp.GRB.MINIMIZE)

    # Add constraints
    m.addConstr(3*x[0] + 2*x[1] + 5*x[2] + 7*x[3] <= 117, "logistics_footprint")
    m.addConstr(6*x[0] + x[1] + 6*x[2] + 6*x[3] <= 107, "fun_factor")
    m.addConstr(5*x[2] + 7*x[3] >= 17, "water_medical_min_footprint")
    m.addConstr((3*x[0])**2 + (5*x[2])**2 >= 23, "cbrn_water_min_footprint_sq")
    m.addConstr(3*x[0] + 2*x[1] >= 11, "cbrn_art_min_footprint")
    m.addConstr(2*x[1] + 5*x[2] >= 19, "art_water_min_footprint")
    m.addConstr(3*x[0] + 2*x[1] + 5*x[2] + 7*x[3] >= 19, "total_min_footprint")
    m.addConstr(6*x[0] + x[1] >= 14, "cbrn_art_min_fun")
    m.addConstr(6*x[2] + 6*x[3] >= 20, "water_medical_min_fun")
    m.addConstr(6*x[0] + x[1] + 6*x[2] + 6*x[3] >= 20, "total_min_fun")
    m.addConstr(3*x[0] + 2*x[1] <= 106, "cbrn_art_max_footprint")
    m.addConstr((2*x[1])**2 + (7*x[3])**2 <= 97, "art_medical_max_footprint_sq")
    m.addConstr((2*x[1])**2 + (5*x[2])**2 <= 59, "art_water_max_footprint_sq")
    m.addConstr(3*x[0] + 5*x[2] + 7*x[3] <= 101, "cbrn_water_medical_max_footprint")


    # Optimize model
    m.optimize()

    if m.status == gp.GRB.OPTIMAL:
        for v in m.getVars():
            print(f'{v.varName}: {v.x}')
        print(f'Objective Value: {m.objVal}')
    elif m.status == gp.GRB.INFEASIBLE:
        print("The model is infeasible.")
    else:
        print(f"Optimization ended with status {m.status}")


except gp.GrorbiError as e:
    print(f'Error code {e.errno}: {e.message}')
except AttributeError:
    print('Encountered an attribute error')
```