class BlackScholesFormulaRepository {

  public static double vegaBleed(
      double spot,
      double strike,
      double timeToExpiry,
      double lognormalVol,
      double interestRate,
      double costOfCarry) {

    ArgChecker.isTrue(spot >= 0d, "negative/NaN spot; have {}", spot);
    ArgChecker.isTrue(strike >= 0d, "negative/NaN strike; have {}", strike);
    ArgChecker.isTrue(timeToExpiry >= 0d, "negative/NaN timeToExpiry; have {}", timeToExpiry);
    ArgChecker.isTrue(lognormalVol >= 0d, "negative/NaN lognormalVol; have {}", lognormalVol);
    ArgChecker.isFalse(Double.isNaN(interestRate), "interestRate is NaN");
    ArgChecker.isFalse(Double.isNaN(costOfCarry), "costOfCarry is NaN");

    double rootT = Math.sqrt(timeToExpiry);
    double sigmaRootT = lognormalVol * rootT;
    if (Double.isNaN(sigmaRootT)) {
      sigmaRootT = 1d; //ref value is returned
    }
    if (spot > LARGE * strike || strike > LARGE * spot || rootT < SMALL) {
      return 0d;
    }

    double d1 = 0d;
    double extra = 0d;
    if (Math.abs(spot - strike) < SMALL || (spot > LARGE && strike > LARGE) || rootT > LARGE) {
      double costOvVol =
          (Math.abs(costOfCarry) < SMALL && lognormalVol < SMALL) ? Math.signum(costOfCarry) : costOfCarry / lognormalVol;
      double coefD1 = costOvVol + 0.5 * lognormalVol;
      double tmpD1 = coefD1 * rootT;
      d1 = Double.isNaN(tmpD1) ? 0d : tmpD1;
      double coefExtra =
          interestRate - 0.5 * costOfCarry + 0.5 * costOvVol * costOvVol + 0.125 * lognormalVol * lognormalVol;
      double tmpExtra = Double.isNaN(coefExtra) ? rootT : coefExtra * rootT;
      extra = Double.isNaN(tmpExtra) ? 1d - 0.5 / rootT : tmpExtra - 0.5 / rootT;
    } else {
      if (lognormalVol > LARGE) {
        d1 = 0.5 * sigmaRootT;
        extra = 0.125 * lognormalVol * sigmaRootT;
      } else {
        if (lognormalVol < SMALL) {
          double resLogRatio = Math.log(spot / strike) / rootT;
          double d1Tmp = (resLogRatio + costOfCarry * rootT) / lognormalVol;
          d1 = Double.isNaN(d1Tmp) ? 1d : d1Tmp;
          double tmpExtra =
              (-0.5 * resLogRatio * resLogRatio / rootT + 0.5 * costOfCarry * costOfCarry * rootT) / lognormalVol / lognormalVol;
          extra = Double.isNaN(tmpExtra) ? 1d : extra;
        } else {
          double resLogRatio = Math.log(spot / strike) / sigmaRootT;
          double tmp = resLogRatio + costOfCarry * rootT / lognormalVol;
          d1 = tmp + 0.5 * sigmaRootT;
          double pDivTmp = interestRate - 0.5 * costOfCarry * (1d - costOfCarry / lognormalVol / lognormalVol);
          double pDiv = Double.isNaN(pDivTmp) ? rootT : pDivTmp * rootT;
          extra = pDiv - 0.5 / rootT - 0.5 * resLogRatio * resLogRatio / rootT + 0.125 * lognormalVol * sigmaRootT;
        }
      }
    }
    double coef = 0d;
    if ((interestRate > LARGE && costOfCarry > LARGE) || (-interestRate > LARGE && -costOfCarry > LARGE) ||
        Math.abs(costOfCarry - interestRate) < SMALL) {
      coef = 1d; //ref value is returned
    } else {
      double rate = costOfCarry - interestRate;
      if (rate > LARGE) {
        return costOfCarry > LARGE ? 0d : (extra >= 0d ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY);
      }
      if (-rate > LARGE) {
        return 0d;
      }
      coef = Math.exp(rate * timeToExpiry);
    }

    double norm = NORMAL.getPDF(d1);
    double tmp = spot * coef * extra;
    if (Double.isNaN(tmp)) {
      tmp = coef;
    }

    return norm < SMALL ? 0d : tmp * norm;
  }

  private  BlackScholesFormulaRepository();

}