import { toJstIso } from "@/lib/format/date";
import type { DsLogFile, DsLogType } from "@/lib/types";
/**
* 制御盤(ラズパイ)のログの一覧のサンプルデータ(指示書AY 段階8-1。D10・D24)。
*
* ★種類は実機に合わせる★(設計書 §1.6・§5.2)。★表示名は仮★なので、テストの期待値に表示名を埋め込まない(キーで比べる)。
* ★`name` は実機の形★: `{root の name}/{root からの相対パス}` —
* `<種類>/<種類>.log`(各種類の最新)と `<種類>/<種類>.log.YYYY-MM-DD`(設計書 §5.5。zip の中のパスと同じ。M6)。
* ★実在の店名・ログの中身は入れない★。
*/
export const fixtureDeviceLogTypes: readonly DsLogType[] = [
{ key: "api_client", label: "API 通信(報告間隔の取得・通信の有効/無効)(仮)" },
{ key: "postcondition_security", label: "セキュリティ状態の報告(仮)" },
{ key: "postcondition_kick_action", label: "セコム状態の監視・清掃の起動(仮)" },
{ key: "send_start_sig", label: "清掃開始信号(仮)" },
];
/** fixtures の制御盤のうち、未接続にしておくもの(→ 409 `agent_offline`。D10) */
export const FIXTURE_AGENT_OFFLINE_SERIALS: readonly string[] = ["DS-001"];
const SECOND_MS = 1000;
const HOUR_MS = 60 * 60 * SECOND_MS;
const DAY_MS = 24 * HOUR_MS;
/** 日付つきのファイルを何日分さかのぼって作るか(4種類 × 74日 + 最新5件 ≒ 300件) */
const ROTATED_DAYS = 74;
/**
* 大きさは 1KB〜50MB(★選択の合計が 100MB を超える組み合わせが作れる★。実機は全部で 1.2MB 程度だが、
* 画面の上限の確認のため大きくしてある)。決まった値になるよう添字から作る。
*/
function sizeOf(index: number): number {
return 1024 + ((index * 7919) % 50) * 1024 * 1024;
}
/**
* now から決まった間隔で約300件を作る。
* ★now ちょうど・1時間前ちょうど・3時間前ちょうど・24時間前ちょうど・24時間前の1秒前★ の項目を必ず含める(画面の目視用。
* 境界の正しさは `lib/ds-logs/__tests__/query.test.ts` が持つ)。
*/
export function fixtureDeviceLogItems(now: Date): DsLogFile[] {
const nowMs = now.getTime();
const items: DsLogFile[] = [];
const names = new Set<string>();
const push = (type: string, name: string, modifiedMs: number) => {
if (names.has(name)) return;
names.add(name);
items.push({
file_id: `fx-${items.length + 1}`,
name,
type,
size_bytes: sizeOf(items.length + 1),
modified_at: toJstIso(new Date(modifiedMs)),
});
};
// 各種類の最新(`<種類>.log`): now ちょうど・1時間前・3時間前・24時間前
const latestOffsets = [0, HOUR_MS, 3 * HOUR_MS, DAY_MS];
fixtureDeviceLogTypes.forEach((t, i) => push(t.key, `${t.key}/${t.key}.log`, nowMs - latestOffsets[i]));
// 24時間前の1秒前
const justBefore = nowMs - DAY_MS - SECOND_MS;
const kick = fixtureDeviceLogTypes[2].key;
push(kick, `${kick}/${kick}.log.${toJstIso(new Date(justBefore)).slice(0, 10)}`, justBefore);
// 日付つき(`<種類>.log.YYYY-MM-DD`): その日の 23:59:59 JST に書き終えた形
for (let day = 1; day <= ROTATED_DAYS; day++) {
const date = toJstIso(new Date(nowMs - day * DAY_MS)).slice(0, 10);
const endOfDay = Date.parse(`${date}T23:59:59+09:00`);
fixtureDeviceLogTypes.forEach((t, i) => {
push(t.key, `${t.key}/${t.key}.log.${date}`, Math.min(endOfDay - i * 60 * SECOND_MS, nowMs - SECOND_MS));
});
}
return items;
}
/**
* エクスポートの zip(★中身はダミーの文字だけの小さな正しい zip★。438バイト・無圧縮)。
* ★中のパスは `<種類>/<ファイル名>`★(root はフォルダごと。設計書 §5.2・D24):
* `api_client/api_client.log`・`postcondition_security/postcondition_security.log.2026-10-18`。
* ★実在の店名・ログを入れない★。
*/
export const FIXTURE_EXPORT_ZIP_BASE64 =
"UEsDBBQAAAgAAABgUl1mcufuKQAAACkAAAAZAAAAYXBpX2NsaWVudC9hcGlfY2xpZW50LmxvZ2R1bW15IGxvZyBsaW5lIGZvciBmaXh0dXJlcyAoYXBpX2NsaWVudCkKUEsDBBQAAAgAAABgUl2WWj0hNQAAADUAAAA8AAAAcG9zdGNvbmRpdGlvbl9zZWN1cml0eS9wb3N0Y29uZGl0aW9uX3NlY3VyaXR5LmxvZy4yMDI2LTEwLTE4ZHVtbXkgbG9nIGxpbmUgZm9yIGZpeHR1cmVzIChwb3N0Y29uZGl0aW9uX3NlY3VyaXR5KQpQSwECFAAUAAAIAAAAYFJdZnLn7ikAAAApAAAAGQAAAAAAAAAAAAAAAAAAAAAAYXBpX2NsaWVudC9hcGlfY2xpZW50LmxvZ1BLAQIUABQAAAgAAABgUl2WWj0hNQAAADUAAAA8AAAAAAAAAAAAAAAAAGAAAABwb3N0Y29uZGl0aW9uX3NlY3VyaXR5L3Bvc3Rjb25kaXRpb25fc2VjdXJpdHkubG9nLjIwMjYtMTAtMThQSwUGAAAAAAIAAgCxAAAA7wAAAAAA";