package pl.edu.pw.mini.sg.solver.gurobisolver

import gurobi._
import pl.edu.pw.mini.sg.solver.{Solver, SolverInfo}


class GurobiSolver(config: GurobiConfig) extends Solver {
  override type VariableType = GurobiVariable
  override protected type InnerLinExprType = GRBLinExpr
  override type LinExprType = GurobiLinExpr
  override type ConstraintType = GurobiConstraint
  override type ModelType = GurobiSolverModel

  private lazy val env: GRBEnv = new GRBEnv()

  override def createModel: ModelType = {
    configure(config)
    new GurobiSolverModel(new GRBModel(env))
  }

  private def configure(config: GurobiConfig): Unit = {
      env.set(GRB.IntParam.Threads, config.threads)
      env.set(GRB.IntParam.NumericFocus, config.numericFocus)
      env.set(GRB.DoubleParam.FeasibilityTol, config.feasibilityTol)
      env.set(GRB.DoubleParam.IntFeasTol, config.intFeasTol)
  }

  override val solverInfo: SolverInfo = SolverInfo(
    "Gurobi",
    s"${GRB.VERSION_MAJOR}.${GRB.VERSION_MINOR}.${GRB.VERSION_TECHNICAL}"
  )

  override def close(): Unit = {
    env.dispose()
  }

}
