import { generatePid } from "../../utils/paragraph";
import bignumber from "bignumber.js";

describe("generatePid", () => {
  it("中间插段：nextPid比prev，前缀同一位", async () => {
    const prevPid = "1709011048468500000";
    const nextPid = "1709011048508500000";
    const resultPid = generatePid(prevPid, nextPid);
    // 前缀位，前10位保持不变
    expect(resultPid.slice(0, 10)).toStrictEqual(prevPid.slice(0, 10));
    //  resultPid 必须比 prevPid 大
    expect(bignumber(resultPid).minus(prevPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid 必须比 nextPid 小
    expect(bignumber(nextPid).minus(resultPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid结果位数正确
    expect(resultPid.length).toStrictEqual(19);
  });

  it("中间插段：nextPid比prev，前缀同一位，后缀不满需补位", async () => {
    const prevPid = "1709011048008500000";
    const nextPid = "1709011048078500000";
    const resultPid = generatePid(prevPid, nextPid);
    // 前缀位，前10位保持不变
    expect(resultPid.slice(0, 10)).toStrictEqual(prevPid.slice(0, 10));
    //  resultPid 必须比 prevPid 大
    expect(bignumber(resultPid).minus(prevPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid 必须比 nextPid 小
    expect(bignumber(nextPid).minus(resultPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid结果位数正确
    expect(resultPid.length).toStrictEqual(19);
  });

  it("中间插段：nextPid比prev，大1位", async () => {
    const prevPid = "1709011048368500000";
    const nextPid = "1709011049238500000";
    const resultPid = generatePid(prevPid, nextPid);
    // 前缀位，前10位，和 prevPid 一致
    expect(resultPid.slice(0, 10)).toStrictEqual(prevPid.slice(0, 10));
    // 前缀位，前10位，和 nextPid-1 一致
    expect(resultPid.slice(0, 10)).toStrictEqual(String(parseInt(nextPid.slice(0, 10), 10) - 1));
    //  resultPid 必须比 prevPid 大
    expect(bignumber(resultPid).minus(prevPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid 必须比 nextPid 小
    expect(bignumber(nextPid).minus(resultPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid结果位数正确
    expect(resultPid.length).toStrictEqual(19);
  });

  it("中间插段：nextPid比prev，大1位，且后缀位相加存在进位", async () => {
    const prevPid = "1709011048968500000";
    const nextPid = "1709011049908500000";
    const resultPid = generatePid(prevPid, nextPid);
    // 前缀位，前10位，和 prevPid+1 一致
    expect(resultPid.slice(0, 10)).toStrictEqual(String(parseInt(prevPid.slice(0, 10), 10) + 1));
    // 前缀位，前10位 和 nextPid 一致
    expect(resultPid.slice(0, 10)).toStrictEqual(nextPid.slice(0, 10));
    //  resultPid 必须比 prevPid 大
    expect(bignumber(resultPid).minus(prevPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid 必须比 nextPid 小
    expect(bignumber(nextPid).minus(resultPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid结果位数正确
    expect(resultPid.length).toStrictEqual(19);
  });

  it("中间插段：nextPid比prev，大1位，且后缀位存在00", async () => {
    const prevPid = "1709011048000500000";
    const nextPid = "1709011049008500000";
    const resultPid = generatePid(prevPid, nextPid);
    // 前缀位，前10位，和 prevPid 一致
    expect(resultPid.slice(0, 10)).toStrictEqual(prevPid.slice(0, 10));
    //  resultPid 必须比 prevPid 大
    expect(bignumber(resultPid).minus(prevPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid 必须比 nextPid 小
    expect(bignumber(nextPid).minus(resultPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid结果位数正确
    expect(resultPid.length).toStrictEqual(19);
  });

  it("中间插段：nextPid比prev，大2位", async () => {
    const prevPid = "1709011048368500000";
    const nextPid = "1709011050238500000";
    const resultPid = generatePid(prevPid, nextPid);
    // 前缀位，前10位，和 prevPid+1 一致
    expect(resultPid.slice(0, 10)).toStrictEqual(String(parseInt(prevPid.slice(0, 10), 10) + 1));
    // 前缀位，前10位，和 nextPid-1 一致
    expect(resultPid.slice(0, 10)).toStrictEqual(String(parseInt(nextPid.slice(0, 10), 10) - 1));
    //  resultPid 必须比 prevPid 大
    expect(bignumber(resultPid).minus(prevPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid 必须比 nextPid 小
    expect(bignumber(nextPid).minus(resultPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid结果位数正确
    expect(resultPid.length).toStrictEqual(19);
  });

  it("中间插段：nextPid比prev，大2位，且后缀位相加存在进位", async () => {
    const prevPid = "1709011048968500000";
    const nextPid = "1709011050908500000";
    const resultPid = generatePid(prevPid, nextPid);
    // 前缀位，前10位，和 prevPid+1 一致
    expect(resultPid.slice(0, 10)).toStrictEqual(String(parseInt(prevPid.slice(0, 10), 10) + 1));
    // 前缀位，前10位，和 nextPid-1 一致
    expect(resultPid.slice(0, 10)).toStrictEqual(String(parseInt(nextPid.slice(0, 10), 10) - 1));
    //  resultPid 必须比 prevPid 大
    expect(bignumber(resultPid).minus(prevPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid 必须比 nextPid 小
    expect(bignumber(nextPid).minus(resultPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid结果位数正确
    expect(resultPid.length).toStrictEqual(19);
  });

  it("中间插段：nextPid比prev，大2位，且后缀位存在00", async () => {
    const prevPid = "1709011048000500000";
    const nextPid = "1709011050008500000";
    const resultPid = generatePid(prevPid, nextPid);
    // 前缀位，前10位，和 prevPid+1 一致
    expect(resultPid.slice(0, 10)).toStrictEqual(String(parseInt(prevPid.slice(0, 10), 10) + 1));
    // 前缀位，前10位，和 nextPid-1 一致
    expect(resultPid.slice(0, 10)).toStrictEqual(String(parseInt(nextPid.slice(0, 10), 10) - 1));
    //  resultPid 必须比 prevPid 大
    expect(bignumber(resultPid).minus(prevPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid 必须比 nextPid 小
    expect(bignumber(nextPid).minus(resultPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid结果位数正确
    expect(resultPid.length).toStrictEqual(19);
  });

  it("中间插段：nextPid比prev，大偶数位", async () => {
    const prevPid = "1709011048368500000";
    const nextPid = "1714012050238500000";
    const resultPid = generatePid(prevPid, nextPid);
    // 前缀位，前10位，和 prevPid+1 一致
    expect(resultPid.slice(0, 10)).toStrictEqual(
      String((parseInt(prevPid.slice(0, 10), 10) + parseInt(nextPid.slice(0, 10), 10)) / 2)
    );
    //  resultPid 必须比 prevPid 大
    expect(bignumber(resultPid).minus(prevPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid 必须比 nextPid 小
    expect(bignumber(nextPid).minus(resultPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid结果位数正确
    expect(resultPid.length).toStrictEqual(19);
  });

  it("中间插段：nextPid比prev，大偶数位，且后缀位相加存在进位", async () => {
    const prevPid = "1709011048968500000";
    const nextPid = "1714012050908500000";
    const resultPid = generatePid(prevPid, nextPid);
    // 前缀位，前10位，和 prevPid+1 一致
    expect(resultPid.slice(0, 10)).toStrictEqual(
      String((parseInt(prevPid.slice(0, 10), 10) + parseInt(nextPid.slice(0, 10), 10)) / 2)
    );
    //  resultPid 必须比 prevPid 大
    expect(bignumber(resultPid).minus(prevPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid 必须比 nextPid 小
    expect(bignumber(nextPid).minus(resultPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid结果位数正确
    expect(resultPid.length).toStrictEqual(19);
  });

  it("中间插段：nextPid比prev，大偶数位，且后缀位存在00", async () => {
    const prevPid = "1709011048000500000";
    const nextPid = "1714012050008500000";
    const resultPid = generatePid(prevPid, nextPid);
    // 前缀位，前10位，和 prevPid+1 一致
    expect(resultPid.slice(0, 10)).toStrictEqual(
      String((parseInt(prevPid.slice(0, 10), 10) + parseInt(nextPid.slice(0, 10), 10)) / 2)
    );
    //  resultPid 必须比 prevPid 大
    expect(bignumber(resultPid).minus(prevPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid 必须比 nextPid 小
    expect(bignumber(nextPid).minus(resultPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid结果位数正确
    expect(resultPid.length).toStrictEqual(19);
  });

  it("中间插段：nextPid比prev，大奇数位", async () => {
    const prevPid = "1709011048368500000";
    const nextPid = "1714012051238500000";
    const resultPid = generatePid(prevPid, nextPid);
    // 前缀位，前10位，和 prevPid+1 一致
    expect(resultPid.slice(0, 10)).toStrictEqual(
      String((parseInt(prevPid.slice(0, 10), 10) + parseInt(nextPid.slice(0, 10), 10) - 1) / 2)
    );
    //  resultPid 必须比 prevPid 大
    expect(bignumber(resultPid).minus(prevPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid 必须比 nextPid 小
    expect(bignumber(nextPid).minus(resultPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid结果位数正确
    expect(resultPid.length).toStrictEqual(19);
  });

  it("中间插段：nextPid比prev，大奇数位，且后缀位相加存在进位", async () => {
    const prevPid = "1709011048968500000";
    const nextPid = "1714012051908500000";
    const resultPid = generatePid(prevPid, nextPid);
    // 前缀位，前10位，和 prevPid+1 一致
    expect(resultPid.slice(0, 10)).toStrictEqual(
      String((parseInt(prevPid.slice(0, 10), 10) + parseInt(nextPid.slice(0, 10), 10) + 1) / 2)
    );
    //  resultPid 必须比 prevPid 大
    expect(bignumber(resultPid).minus(prevPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid 必须比 nextPid 小
    expect(bignumber(nextPid).minus(resultPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid结果位数正确
    expect(resultPid.length).toStrictEqual(19);
  });

  it("中间插段：nextPid比prev，大奇数位，且后缀位存在00", async () => {
    const prevPid = "1709011048000500000";
    const nextPid = "1714012051008500000";
    const resultPid = generatePid(prevPid, nextPid);
    // 前缀位，前10位，和 prevPid+1 一致
    expect(resultPid.slice(0, 10)).toStrictEqual(
      String((parseInt(prevPid.slice(0, 10), 10) + parseInt(nextPid.slice(0, 10), 10) - 1) / 2)
    );
    //  resultPid 必须比 prevPid 大
    expect(bignumber(resultPid).minus(prevPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid 必须比 nextPid 小
    expect(bignumber(nextPid).minus(resultPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid结果位数正确
    expect(resultPid.length).toStrictEqual(19);
  });

  it("顶部插段：只存在nextPid", async () => {
    const prevPid = undefined;
    const nextPid = "1709011049008500000";
    const resultPid = generatePid(prevPid, nextPid);
    // 前缀位，前13位保持不变
    expect(resultPid.slice(0, 13)).toStrictEqual(nextPid.slice(0, 13));
    //  resultPid 必须比 nextPid 小
    expect(bignumber(nextPid).minus(resultPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid结果位数正确
    expect(resultPid.length).toStrictEqual(19);
  });

  it("顶部插段：只存在nextPid，后缀位需补位", async () => {
    const prevPid = undefined;
    const nextPid = "1709011049008050000";
    const resultPid = generatePid(prevPid, nextPid);
    // 前缀位，前13位保持不变
    expect(resultPid.slice(0, 13)).toStrictEqual(nextPid.slice(0, 13));
    //  resultPid 必须比 nextPid 小
    expect(bignumber(nextPid).minus(resultPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid结果位数正确
    expect(resultPid.length).toStrictEqual(19);
  });

  it("尾部插段：只存在prevPid", async () => {
    const prevPid = "1709011049408500000";
    const nextPid = undefined;
    const resultPid = generatePid(prevPid, nextPid);
    //  resultPid 必须比 prevPid 大
    expect(bignumber(resultPid).minus(prevPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid结果位数正确
    expect(resultPid.length).toStrictEqual(19);
  });

  it("尾部插段：只存在prevPid，后缀位前置有00", async () => {
    const prevPid = "1709011049008500000";
    const nextPid = undefined;
    const resultPid = generatePid(prevPid, nextPid);
    //  resultPid 必须比 prevPid 大
    expect(bignumber(resultPid).minus(prevPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid结果位数正确
    expect(resultPid.length).toStrictEqual(19);
  });

  it("尾部插段", async () => {
    const prevPid = "1709011049999500000";
    const nextPid = undefined;
    const resultPid = generatePid(prevPid, nextPid);
    //  resultPid 必须比 prevPid 大
    expect(bignumber(resultPid).minus(prevPid).isGreaterThan(0)).toBeTruthy();
    //  resultPid结果位数正确
    expect(resultPid.length).toStrictEqual(19);
  });

  it("空白插段：不存在prevPid、nextPid", async () => {
    const prevPid = undefined;
    const nextPid = undefined;
    const resultPid = generatePid(prevPid, nextPid);
    const nowTimestamp = new Date().getTime();
    // 后缀位：500000
    expect(resultPid.slice(13)).toStrictEqual("500000");
    // 前缀位，和当前时间戳，偏差在1s内
    expect(bignumber(resultPid.slice(0, 13)).minus(nowTimestamp).isGreaterThan(-1000)).toBeTruthy();
    // 前缀位，和当前时间戳，偏差在1s内
    expect(bignumber(resultPid.slice(0, 13)).minus(nowTimestamp).isLessThan(1000)).toBeTruthy();
    //  resultPid结果位数正确
    expect(resultPid.length).toStrictEqual(19);
  });
});
