```json
{
  "sym_variables": [
    ("x0", "oranges"),
    ("x1", "kiwis"),
    ("x2", "bananas")
  ],
  "objective_function": "7.89 * x0 + 1.44 * x1 + 4.36 * x2",
  "constraints": [
    "6 * x0 + 6 * x1 >= 34",
    "6 * x1 + 6 * x2 >= 17",
    "6 * x0 + 6 * x2 >= 31",
    "5 * x0 - 10 * x1 >= 0",
    "6 * x0 + 6 * x2 <= 98",
    "6 * x0 + 6 * x1 <= 62",
    "6 * x1 + 6 * x2 <= 92",
    "6 * x0 + 6 * x1 + 6 * x2 <= 49",
    "12 * x1 + 8 * x2 <= 90",
    "9 * x0 + 12 * x1 <= 85",
    "9 * x0 + 12 * x1 + 8 * x2 <= 85",
    "6 * x0 <= 117",
    "9 * x0 <= 108",
    "6 * x1 <= 117",
    "12 * x1 <= 108",
    "6 * x2 <= 117",
    "8 * x2 <= 108"
  ]
}
```

```python
import gurobipy as gp

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

    # Create variables
    oranges = m.addVar(vtype=gp.GRB.INTEGER, name="oranges")
    kiwis = m.addVar(vtype=gp.GRB.INTEGER, name="kiwis")
    bananas = m.addVar(vtype=gp.GRB.INTEGER, name="bananas")

    # Set objective function
    m.setObjective(7.89 * oranges + 1.44 * kiwis + 4.36 * bananas, gp.GRB.MAXIMIZE)

    # Add constraints
    m.addConstr(6 * oranges + 6 * kiwis >= 34, "fat_constraint1")
    m.addConstr(6 * kiwis + 6 * bananas >= 17, "fat_constraint2")
    m.addConstr(6 * oranges + 6 * bananas >= 31, "fat_constraint3")
    m.addConstr(5 * oranges - 10 * kiwis >= 0, "orange_kiwi_ratio")
    m.addConstr(6 * oranges + 6 * bananas <= 98, "fat_constraint4")
    m.addConstr(6 * oranges + 6 * kiwis <= 62, "fat_constraint5")
    m.addConstr(6 * kiwis + 6 * bananas <= 92, "fat_constraint6")
    m.addConstr(6 * oranges + 6 * kiwis + 6 * bananas <= 49, "fat_constraint7")
    m.addConstr(12 * kiwis + 8 * bananas <= 90, "cost_constraint1")
    m.addConstr(9 * oranges + 12 * kiwis <= 85, "cost_constraint2")
    m.addConstr(9 * oranges + 12 * kiwis + 8 * bananas <= 85, "cost_constraint3")

    # Resource constraints (given in the problem description)
    m.addConstr(6 * oranges <= 117, "fat_oranges_limit")
    m.addConstr(9 * oranges <= 108, "cost_oranges_limit")
    m.addConstr(6 * kiwis <= 117, "fat_kiwis_limit")
    m.addConstr(12 * kiwis <= 108, "cost_kiwis_limit")
    m.addConstr(6 * bananas <= 117, "fat_bananas_limit")
    m.addConstr(8 * bananas <= 108, "cost_bananas_limit")


    # Optimize model
    m.optimize()

    if m.status == gp.GRB.OPTIMAL:
        print('Obj: %g' % m.objVal)
        print('oranges:', oranges.x)
        print('kiwis:', kiwis.x)
        print('bananas:', bananas.x)
    elif m.status == gp.GRB.INFEASIBLE:
        print('The model is infeasible.')
    else:
        print('Optimization ended with status %d' % m.status)


except gp.GurobiError as e:
    print('Error code ' + str(e.errno) + ': ' + str(e))

except AttributeError:
    print('Encountered an attribute error')
```