"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getSqrtRatioAtTick = exports.getAmountsForLiquidity = void 0;
/* eslint-disable no-negated-condition */
/* eslint-disable complexity */
const ethers_1 = require("ethers");
const FixedPoint96 = {
    RESOLUTION: ethers_1.BigNumber.from(2).pow(96),
    Q96: ethers_1.BigNumber.from(2).pow(192),
};
function mulDiv(x, y, z) {
    return x.mul(y).div(z);
}
function getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity) {
    if (sqrtRatioAX96.gt(sqrtRatioBX96)) {
        [sqrtRatioAX96, sqrtRatioBX96] = [sqrtRatioBX96, sqrtRatioAX96];
    }
    return mulDiv(liquidity.shl(96), sqrtRatioBX96.sub(sqrtRatioAX96), sqrtRatioBX96).div(sqrtRatioAX96);
}
function getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity) {
    if (sqrtRatioAX96.gt(sqrtRatioBX96)) {
        [sqrtRatioAX96, sqrtRatioBX96] = [sqrtRatioBX96, sqrtRatioAX96];
    }
    return mulDiv(liquidity, sqrtRatioBX96.sub(sqrtRatioAX96), FixedPoint96.Q96);
}
function getAmountsForLiquidity(sqrtRatioX96, sqrtRatioAX96, sqrtRatioBX96, liquidity) {
    if (sqrtRatioAX96.gt(sqrtRatioBX96)) {
        [sqrtRatioAX96, sqrtRatioBX96] = [sqrtRatioBX96, sqrtRatioAX96];
    }
    let amount0 = ethers_1.BigNumber.from(0);
    let amount1 = ethers_1.BigNumber.from(0);
    if (sqrtRatioX96.lte(sqrtRatioAX96)) {
        amount0 = getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);
    }
    else if (sqrtRatioX96.lt(sqrtRatioBX96)) {
        amount0 = getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, liquidity);
        amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, liquidity);
    }
    else {
        amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);
    }
    return [amount0, amount1];
}
exports.getAmountsForLiquidity = getAmountsForLiquidity;
// const MaxUint256 = BigNumber.from('0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff')
// const Q32 = BigNumber.from(2).pow(32)
// const ZERO = BigNumber.from(0)
// const ONE = BigNumber.from(1)
// function mulShift(x: BigNumber, y: string): BigNumber {
//   return x.mul(BigNumber.from(y)).div(MaxUint256)
// }
/**
 * Returns the sqrt ratio as a Q64.96 for the given tick. The sqrt ratio is computed as sqrt(1.0001)^tick
 * @param tick the tick for which to compute the sqrt ratio
 */
function getSqrtRatioAtTick(tick) {
    if (tick < -887272 || tick > 887272 || !Number.isInteger(tick)) {
        throw new Error('TICK');
    }
    const X96 = ethers_1.BigNumber.from('2').pow('96');
    const PRECISION = 10 ** 36;
    const BNPRECISION = ethers_1.BigNumber.from('10').pow('36');
    let ratio = 1.0001 ** tick;
    // After squaring the smallest prec we get is e-20
    ratio = Math.sqrt(ratio) * PRECISION;
    return ethers_1.BigNumber.from(ratio.toString()).mul(X96).div(BNPRECISION);
}
exports.getSqrtRatioAtTick = getSqrtRatioAtTick;
