#!/usr/bin/env node

// 요청 예시: https://www.everfactory.kr/api/contents/update?date=YYYYMMDD
// 사용법
// 1) 오늘(가장 최신)부터 특정 일자까지 요청:
//    node datareq/datareq.js 20251014
// 2) 특정 최신일자부터 특정 과거일자까지 요청:
//    node datareq/datareq.js 20251015 20251001
// 환경변수로 호출 간 지연(ms) 조절: RATE_MS=500 node datareq/datareq.js 20251014

const BASE_URL = "http://localhost:9551/api/contents/update";
const DEFAULT_RATE_MS = Number(process.env.RATE_MS || 400);

function isValidYyyyMmDd(value) {
  return typeof value === "string" && /^\d{8}$/.test(value);
}

function truncateText(text, maxLen = 256) {
  if (typeof text !== "string") return "";
  return text.length > maxLen ? text.slice(0, maxLen) : text;
}

function parseYyyyMmDdToDate(yyyyMmDd) {
  const year = Number(yyyyMmDd.slice(0, 4));
  const month = Number(yyyyMmDd.slice(4, 6)) - 1; // 0-based
  const day = Number(yyyyMmDd.slice(6, 8));
  // Date(YYYY, M, D)는 로컬 타임존 기준. 간단성을 위해 로컬 기준 사용.
  return new Date(year, month, day);
}

function formatDateToYyyyMmDd(date) {
  const y = String(date.getFullYear());
  const m = String(date.getMonth() + 1).padStart(2, "0");
  const d = String(date.getDate()).padStart(2, "0");
  return `${y}${m}${d}`;
}

function addDays(date, delta) {
  const next = new Date(date);
  next.setDate(next.getDate() + delta);
  return next;
}

async function sleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

async function requestForDate(dateStr) {
  const url = `${BASE_URL}?date=${dateStr}`;
  try {
    const res = await fetch(url, { method: "GET" });
    const text = await res.text().catch(() => "");
    if (!res.ok) {
      const preview = truncateText(text, 256);
      console.error(`[FAIL] ${dateStr} | ${url} -> ${res.status} ${res.statusText} ${preview ? `| ${preview}` : ""}`);
      return { ok: false, status: res.status, body: text };
    }
    const preview = truncateText(text, 256);
    console.log(`[OK]   ${dateStr} | ${url} -> ${preview || res.status}`);
    return { ok: true, status: res.status, body: text };
  } catch (err) {
    const errMsg = err instanceof Error ? err.message : String(err);
    console.error(`[ERROR] ${dateStr} | ${url} -> ${truncateText(errMsg, 256)}`);
    return { ok: false, error: err };
  }
}

async function main() {
  const args = process.argv.slice(2);

  if (args.length === 0) {
    console.log("사용법: node datareq/datareq.js <끝일자YYYYMMDD> [시작(최신)일자YYYYMMDD]");
    console.log("예시1: node datareq/datareq.js 20251014");
    console.log("예시2: node datareq/datareq.js 20251015 20251001");
    process.exit(1);
  }

  let newestStr; // 최신일자 (내림차순 시작점)
  let oldestStr; // 종료일자 (내림차순 끝점)

  if (args.length === 1) {
    const today = new Date();
    newestStr = formatDateToYyyyMmDd(today);
    oldestStr = args[0];
  } else {
    // args.length >= 2 인 경우: [최신일자, 종료일자]
    newestStr = args[0];
    oldestStr = args[1];
  }

  if (!isValidYyyyMmDd(newestStr) || !isValidYyyyMmDd(oldestStr)) {
    console.error("날짜 형식은 YYYYMMDD 여야 합니다.");
    process.exit(1);
  }

  let newestDate = parseYyyyMmDdToDate(newestStr);
  let oldestDate = parseYyyyMmDdToDate(oldestStr);

  // 최신 >= 종료 가 아니면 자동 교환
  if (newestDate < oldestDate) {
    const tmp = newestDate;
    newestDate = oldestDate;
    oldestDate = tmp;
    newestStr = formatDateToYyyyMmDd(newestDate);
    oldestStr = formatDateToYyyyMmDd(oldestDate);
  }

  console.log(`요청 범위: 최신 ${newestStr} → 종료 ${oldestStr} (내림차순)`);
  console.log(`요청 간 지연: ${DEFAULT_RATE_MS}ms`);

  let current = newestDate;
  while (current >= oldestDate) {
    const dateStr = formatDateToYyyyMmDd(current);
    await requestForDate(dateStr);
    // 너무 빠른 연속 호출 방지
    await sleep(DEFAULT_RATE_MS);
    current = addDays(current, -1);
  }

  console.log("모든 요청이 완료되었습니다.");
}

// Node 18+ 환경 가정: fetch 전역 제공. 없으면 종료 안내.
if (typeof fetch !== "function") {
  console.error("현재 Node 런타임에 fetch가 없습니다. Node 18+를 사용하거나 폴리필을 추가하세요.");
  process.exit(1);
}

main().catch((err) => {
  console.error("예상치 못한 오류:", err);
  process.exit(1);
});


