#!/usr/bin/env python3
"""
DOCplex 2.29.245 Implementation for Browser Web Accelerator Optimization
"""

from docplex.mp.model import Model

def optimize_browser_web_accelerators():
    """Optimize the selection of web client accelerators for maximum browser compatibility."""
    
    # 1. MODEL & DATA SETUP
    mdl = Model(name="browser_web_accelerator_optimization")
    
    # Data from the problem context
    browsers = [
        {"browser_id": 1, "market_share": 0.35},
        {"browser_id": 2, "market_share": 0.25},
        {"browser_id": 3, "market_share": 0.15}
    ]
    
    accelerator_compatibilities = [
        {"accelerator_id": 1, "browser_id": 1, "compatibility_score": 0.9},
        {"accelerator_id": 1, "browser_id": 2, "compatibility_score": 0.8},
        {"accelerator_id": 2, "browser_id": 1, "compatibility_score": 0.85},
        {"accelerator_id": 2, "browser_id": 3, "compatibility_score": 0.7},
        {"accelerator_id": 3, "browser_id": 2, "compatibility_score": 0.75},
        {"accelerator_id": 3, "browser_id": 3, "compatibility_score": 0.65}
    ]
    
    max_accelerators = 3
    
    # Create dictionaries for easy access
    browser_market_share = {b["browser_id"]: b["market_share"] for b in browsers}
    compatibility_scores = {(ac["accelerator_id"], ac["browser_id"]): ac["compatibility_score"] for ac in accelerator_compatibilities}
    
    # Extract unique accelerator and browser IDs
    accelerator_ids = list(set(ac["accelerator_id"] for ac in accelerator_compatibilities))
    browser_ids = list(set(b["browser_id"] for b in browsers))
    
    # CRITICAL: Validate array lengths to prevent IndexError
    assert len(accelerator_ids) == 3, "Expected 3 accelerators"
    assert len(browser_ids) == 3, "Expected 3 browsers"
    
    # 2. VARIABLES
    x = {i: mdl.binary_var(name=f"x_{i}") for i in accelerator_ids}  # Accelerator selection
    y = {j: mdl.binary_var(name=f"y_{j}") for j in browser_ids}     # Browser compatibility
    
    # 3. OBJECTIVE FUNCTION
    objective = mdl.sum(browser_market_share[j] * y[j] for j in browser_ids)
    mdl.maximize(objective)
    
    # 4. CONSTRAINTS
    
    # Maximum Accelerators Constraint
    mdl.add_constraint(mdl.sum(x[i] for i in accelerator_ids) <= max_accelerators, ctname="max_accelerators")
    
    # Minimum Compatibility Constraint
    for i in accelerator_ids:
        mdl.add_constraint(mdl.sum(compatibility_scores[(i, j)] * y[j] for j in browser_ids) >= x[i], ctname=f"min_compat_{i}")
    
    # Browser Compatibility Constraint
    for j in browser_ids:
        mdl.add_constraint(y[j] <= mdl.sum(compatibility_scores[(i, j)] * x[i] for i in accelerator_ids), ctname=f"browser_compat_{j}")
    
    # 5. SOLVING & RESULTS
    solution = mdl.solve()
    
    if solution:
        print(f"Optimal value: {solution.objective_value}")
        for i in accelerator_ids:
            if solution.get_value(x[i]) > 0.5:
                print(f"Accelerator {i} is selected")
        for j in browser_ids:
            if solution.get_value(y[j]) > 0.5:
                print(f"Browser {j} is compatible")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")
    
    return mdl

# Execute the optimization
if __name__ == "__main__":
    optimize_browser_web_accelerators()