import * as plugins from '../../plugins.js';
import { DcRouterDb } from '../classes.dcrouter-db.js';

const getDb = () => DcRouterDb.getInstance().getDb();

@plugins.smartdata.Collection(() => getDb())
export class AccountingSessionDoc extends plugins.smartdata.SmartDataDbDoc<AccountingSessionDoc, AccountingSessionDoc> {
  @plugins.smartdata.unI()
  @plugins.smartdata.svDb()
  public sessionId!: string;

  @plugins.smartdata.svDb()
  public username!: string;

  @plugins.smartdata.svDb()
  public macAddress!: string;

  @plugins.smartdata.svDb()
  public nasIpAddress!: string;

  @plugins.smartdata.svDb()
  public nasPort!: number;

  @plugins.smartdata.svDb()
  public nasPortType!: string;

  @plugins.smartdata.svDb()
  public nasIdentifier!: string;

  @plugins.smartdata.svDb()
  public vlanId!: number;

  @plugins.smartdata.svDb()
  public framedIpAddress!: string;

  @plugins.smartdata.svDb()
  public calledStationId!: string;

  @plugins.smartdata.svDb()
  public callingStationId!: string;

  @plugins.smartdata.svDb()
  public startTime!: number;

  @plugins.smartdata.svDb()
  public endTime!: number;

  @plugins.smartdata.svDb()
  public lastUpdateTime!: number;

  @plugins.smartdata.index()
  @plugins.smartdata.svDb()
  public status!: 'active' | 'stopped' | 'terminated';

  @plugins.smartdata.svDb()
  public terminateCause!: string;

  @plugins.smartdata.svDb()
  public inputOctets!: number;

  @plugins.smartdata.svDb()
  public outputOctets!: number;

  @plugins.smartdata.svDb()
  public inputPackets!: number;

  @plugins.smartdata.svDb()
  public outputPackets!: number;

  @plugins.smartdata.svDb()
  public sessionTime!: number;

  @plugins.smartdata.svDb()
  public serviceType!: string;

  constructor() {
    super();
  }

  public static async findBySessionId(sessionId: string): Promise<AccountingSessionDoc | null> {
    return await AccountingSessionDoc.getInstance({ sessionId });
  }

  public static async findActive(): Promise<AccountingSessionDoc[]> {
    return await AccountingSessionDoc.getInstances({ status: 'active' });
  }

  public static async findByUsername(username: string): Promise<AccountingSessionDoc[]> {
    return await AccountingSessionDoc.getInstances({ username });
  }

  public static async findByNas(nasIpAddress: string): Promise<AccountingSessionDoc[]> {
    return await AccountingSessionDoc.getInstances({ nasIpAddress });
  }

  public static async findByVlan(vlanId: number): Promise<AccountingSessionDoc[]> {
    return await AccountingSessionDoc.getInstances({ vlanId });
  }

  public static async findStoppedBefore(cutoffTime: number): Promise<AccountingSessionDoc[]> {
    return await AccountingSessionDoc.getInstances({
      status: { $in: ['stopped', 'terminated'] } as any,
      endTime: { $lt: cutoffTime, $gt: 0 } as any,
    });
  }
}
