Here's the formulation of the linear program and the Gurobi code to solve it:

**Decision Variables:**

* `x`: Number of dining tables to produce
* `y`: Number of bed frames to produce

**Objective Function:**

Maximize profit: `300x + 400y`

**Constraints:**

* Oak wood constraint: `3x + 5y <= 300`
* Mahogany wood constraint: `5x + 2y <= 400`
* Non-negativity constraints: `x >= 0`, `y >= 0`


```python
import gurobipy as gp
from gurobipy import GRB

# Create a new model
m = gp.Model("woodshop")

# Create variables
x = m.addVar(vtype=GRB.CONTINUOUS, name="dining_tables")  # Allow fractional tables for now
y = m.addVar(vtype=GRB.CONTINUOUS, name="bed_frames")    # Allow fractional bed frames

# Set objective function
m.setObjective(300*x + 400*y, GRB.MAXIMIZE)

# Add constraints
m.addConstr(3*x + 5*y <= 300, "oak_constraint")
m.addConstr(5*x + 2*y <= 400, "mahogany_constraint")

# Optimize model
m.optimize()

# Print results
if m.status == GRB.OPTIMAL:
    print(f"Optimal Solution Found:")
    print(f"Number of Dining Tables: {x.x}")
    print(f"Number of Bed Frames: {y.x}")
    print(f"Maximum Profit: ${m.objVal}")

    # Check if solution is integer and suggest rounding if not
    if x.x != int(x.x) or y.x != int(y.x):
        print("\nNote: The optimal solution involves fractional furniture.  In a real-world scenario, you would likely round down to the nearest integer to get a feasible production plan.")
        print(f"Suggested Rounded Solution:")
        print(f"Number of Dining Tables: {int(x.x)}")
        print(f"Number of Bed Frames: {int(y.x)}")
        rounded_profit = 300*int(x.x) + 400*int(y.x)
        print(f"Approximate Profit (Rounded): ${rounded_profit}")


elif m.status == GRB.INFEASIBLE:
    print("The model is infeasible.  No solution can satisfy all constraints.")
else:
    print(f"Optimization terminated with status {m.status}")

```
