// Code generated by protoc-gen-ts-server. DO NOT EDIT.
// source: worldmonitor/military/v1/service.proto

export interface ListMilitaryFlightsRequest {
  pageSize: number;
  cursor: string;
  neLat: number;
  neLon: number;
  swLat: number;
  swLon: number;
  operator: MilitaryOperator;
  aircraftType: MilitaryAircraftType;
}

export interface ListMilitaryFlightsResponse {
  flights: MilitaryFlight[];
  clusters: MilitaryFlightCluster[];
  pagination?: PaginationResponse;
}

export interface MilitaryFlight {
  id: string;
  callsign: string;
  hexCode: string;
  registration: string;
  aircraftType: MilitaryAircraftType;
  aircraftModel: string;
  operator: MilitaryOperator;
  operatorCountry: string;
  location?: GeoCoordinates;
  altitude: number;
  heading: number;
  speed: number;
  verticalRate: number;
  onGround: boolean;
  squawk: string;
  origin: string;
  destination: string;
  lastSeenAt: number;
  firstSeenAt: number;
  confidence: MilitaryConfidence;
  isInteresting: boolean;
  note: string;
  enrichment?: FlightEnrichment;
}

export interface GeoCoordinates {
  latitude: number;
  longitude: number;
}

export interface FlightEnrichment {
  manufacturer: string;
  owner: string;
  operatorName: string;
  typeCode: string;
  builtYear: string;
  confirmedMilitary: boolean;
  militaryBranch: string;
}

export interface MilitaryFlightCluster {
  id: string;
  name: string;
  location?: GeoCoordinates;
  flightCount: number;
  flights: MilitaryFlight[];
  dominantOperator: MilitaryOperator;
  activityType: MilitaryActivityType;
}

export interface PaginationResponse {
  nextCursor: string;
  totalCount: number;
}

export interface GetTheaterPostureRequest {
  theater: string;
}

export interface GetTheaterPostureResponse {
  theaters: TheaterPosture[];
}

export interface TheaterPosture {
  theater: string;
  postureLevel: string;
  activeFlights: number;
  trackedVessels: number;
  activeOperations: string[];
  assessedAt: number;
}

export interface GetAircraftDetailsRequest {
  icao24: string;
}

export interface GetAircraftDetailsResponse {
  details?: AircraftDetails;
  configured: boolean;
}

export interface AircraftDetails {
  icao24: string;
  registration: string;
  manufacturerIcao: string;
  manufacturerName: string;
  model: string;
  typecode: string;
  serialNumber: string;
  icaoAircraftType: string;
  operator: string;
  operatorCallsign: string;
  operatorIcao: string;
  owner: string;
  built: string;
  engines: string;
  categoryDescription: string;
}

export interface GetAircraftDetailsBatchRequest {
  icao24s: string[];
}

export interface GetAircraftDetailsBatchResponse {
  results: Record<string, AircraftDetails>;
  fetched: number;
  requested: number;
  configured: boolean;
}

export interface GetWingbitsStatusRequest {
}

export interface GetWingbitsStatusResponse {
  configured: boolean;
}

export interface GetUSNIFleetReportRequest {
  forceRefresh: boolean;
}

export interface GetUSNIFleetReportResponse {
  report?: USNIFleetReport;
  cached: boolean;
  stale: boolean;
  error: string;
}

export interface USNIFleetReport {
  articleUrl: string;
  articleDate: string;
  articleTitle: string;
  battleForceSummary?: BattleForceSummary;
  vessels: USNIVessel[];
  strikeGroups: USNIStrikeGroup[];
  regions: string[];
  parsingWarnings: string[];
  timestamp: number;
}

export interface BattleForceSummary {
  totalShips: number;
  deployed: number;
  underway: number;
}

export interface USNIVessel {
  name: string;
  hullNumber: string;
  vesselType: string;
  region: string;
  regionLat: number;
  regionLon: number;
  deploymentStatus: string;
  homePort: string;
  strikeGroup: string;
  activityDescription: string;
  articleUrl: string;
  articleDate: string;
}

export interface USNIStrikeGroup {
  name: string;
  carrier: string;
  airWing: string;
  destroyerSquadron: string;
  escorts: string[];
}

export interface ListMilitaryBasesRequest {
  neLat: number;
  neLon: number;
  swLat: number;
  swLon: number;
  zoom: number;
  type: string;
  kind: string;
  country: string;
}

export interface ListMilitaryBasesResponse {
  bases: MilitaryBaseEntry[];
  clusters: MilitaryBaseCluster[];
  totalInView: number;
  truncated: boolean;
}

export interface MilitaryBaseEntry {
  id: string;
  name: string;
  latitude: number;
  longitude: number;
  kind: string;
  countryIso2: string;
  type: string;
  tier: number;
  catAirforce: boolean;
  catNaval: boolean;
  catNuclear: boolean;
  catSpace: boolean;
  catTraining: boolean;
  branch: string;
  status: string;
}

export interface MilitaryBaseCluster {
  latitude: number;
  longitude: number;
  count: number;
  dominantType: string;
  expansionZoom: number;
}

export interface GetWingbitsLiveFlightRequest {
  icao24: string;
}

export interface GetWingbitsLiveFlightResponse {
  flight?: WingbitsLiveFlight;
}

export interface WingbitsLiveFlight {
  icao24: string;
  callsign: string;
  lat: number;
  lon: number;
  altitude: number;
  speed: number;
  heading: number;
  verticalRate: number;
  registration: string;
  model: string;
  operator: string;
  onGround: boolean;
  lastSeen: string;
  depIata: string;
  arrIata: string;
  depTimeUtc: string;
  arrTimeUtc: string;
  depEstimatedUtc: string;
  arrEstimatedUtc: string;
  depDelayedMin: number;
  arrDelayedMin: number;
  flightStatus: string;
  flightDurationMin: number;
  arrTerminal: string;
  photoUrl: string;
  photoLink: string;
  photoCredit: string;
  callsignIata: string;
  airlineName: string;
}

export interface ListDefensePatentsRequest {
  cpcCode: string;
  assignee: string;
  limit: number;
}

export interface ListDefensePatentsResponse {
  patents: DefensePatentFiling[];
  total: number;
  fetchedAt: string;
}

export interface DefensePatentFiling {
  patentId: string;
  title: string;
  date: string;
  assignee: string;
  cpcCode: string;
  cpcDesc: string;
  abstract: string;
  url: string;
}

export type MilitaryActivityType = "MILITARY_ACTIVITY_TYPE_UNSPECIFIED" | "MILITARY_ACTIVITY_TYPE_EXERCISE" | "MILITARY_ACTIVITY_TYPE_PATROL" | "MILITARY_ACTIVITY_TYPE_TRANSPORT" | "MILITARY_ACTIVITY_TYPE_DEPLOYMENT" | "MILITARY_ACTIVITY_TYPE_TRANSIT" | "MILITARY_ACTIVITY_TYPE_UNKNOWN";

export type MilitaryAircraftType = "MILITARY_AIRCRAFT_TYPE_UNSPECIFIED" | "MILITARY_AIRCRAFT_TYPE_FIGHTER" | "MILITARY_AIRCRAFT_TYPE_BOMBER" | "MILITARY_AIRCRAFT_TYPE_TRANSPORT" | "MILITARY_AIRCRAFT_TYPE_TANKER" | "MILITARY_AIRCRAFT_TYPE_AWACS" | "MILITARY_AIRCRAFT_TYPE_RECONNAISSANCE" | "MILITARY_AIRCRAFT_TYPE_HELICOPTER" | "MILITARY_AIRCRAFT_TYPE_DRONE" | "MILITARY_AIRCRAFT_TYPE_PATROL" | "MILITARY_AIRCRAFT_TYPE_SPECIAL_OPS" | "MILITARY_AIRCRAFT_TYPE_VIP" | "MILITARY_AIRCRAFT_TYPE_UNKNOWN";

export type MilitaryConfidence = "MILITARY_CONFIDENCE_UNSPECIFIED" | "MILITARY_CONFIDENCE_LOW" | "MILITARY_CONFIDENCE_MEDIUM" | "MILITARY_CONFIDENCE_HIGH";

export type MilitaryOperator = "MILITARY_OPERATOR_UNSPECIFIED" | "MILITARY_OPERATOR_USAF" | "MILITARY_OPERATOR_USN" | "MILITARY_OPERATOR_USMC" | "MILITARY_OPERATOR_USA" | "MILITARY_OPERATOR_RAF" | "MILITARY_OPERATOR_RN" | "MILITARY_OPERATOR_FAF" | "MILITARY_OPERATOR_GAF" | "MILITARY_OPERATOR_PLAAF" | "MILITARY_OPERATOR_PLAN" | "MILITARY_OPERATOR_VKS" | "MILITARY_OPERATOR_IAF" | "MILITARY_OPERATOR_NATO" | "MILITARY_OPERATOR_OTHER";

export interface FieldViolation {
  field: string;
  description: string;
}

export class ValidationError extends Error {
  violations: FieldViolation[];

  constructor(violations: FieldViolation[]) {
    super("Validation failed");
    this.name = "ValidationError";
    this.violations = violations;
  }
}

export class ApiError extends Error {
  statusCode: number;
  body: string;

  constructor(statusCode: number, message: string, body: string) {
    super(message);
    this.name = "ApiError";
    this.statusCode = statusCode;
    this.body = body;
  }
}

export interface ServerContext {
  request: Request;
  pathParams: Record<string, string>;
  headers: Record<string, string>;
}

export interface ServerOptions {
  onError?: (error: unknown, req: Request) => Response | Promise<Response>;
  validateRequest?: (methodName: string, body: unknown) => FieldViolation[] | undefined;
}

export interface RouteDescriptor {
  method: string;
  path: string;
  handler: (req: Request) => Promise<Response>;
}

export interface MilitaryServiceHandler {
  listMilitaryFlights(ctx: ServerContext, req: ListMilitaryFlightsRequest): Promise<ListMilitaryFlightsResponse>;
  getTheaterPosture(ctx: ServerContext, req: GetTheaterPostureRequest): Promise<GetTheaterPostureResponse>;
  getAircraftDetails(ctx: ServerContext, req: GetAircraftDetailsRequest): Promise<GetAircraftDetailsResponse>;
  getAircraftDetailsBatch(ctx: ServerContext, req: GetAircraftDetailsBatchRequest): Promise<GetAircraftDetailsBatchResponse>;
  getWingbitsStatus(ctx: ServerContext, req: GetWingbitsStatusRequest): Promise<GetWingbitsStatusResponse>;
  getUSNIFleetReport(ctx: ServerContext, req: GetUSNIFleetReportRequest): Promise<GetUSNIFleetReportResponse>;
  listMilitaryBases(ctx: ServerContext, req: ListMilitaryBasesRequest): Promise<ListMilitaryBasesResponse>;
  getWingbitsLiveFlight(ctx: ServerContext, req: GetWingbitsLiveFlightRequest): Promise<GetWingbitsLiveFlightResponse>;
  listDefensePatents(ctx: ServerContext, req: ListDefensePatentsRequest): Promise<ListDefensePatentsResponse>;
}

export function createMilitaryServiceRoutes(
  handler: MilitaryServiceHandler,
  options?: ServerOptions,
): RouteDescriptor[] {
  return [
    {
      method: "GET",
      path: "/api/military/v1/list-military-flights",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const url = new URL(req.url, "http://localhost");
          const params = url.searchParams;
          const body: ListMilitaryFlightsRequest = {
            pageSize: Number(params.get("page_size") ?? "0"),
            cursor: params.get("cursor") ?? "",
            neLat: Number(params.get("ne_lat") ?? "0"),
            neLon: Number(params.get("ne_lon") ?? "0"),
            swLat: Number(params.get("sw_lat") ?? "0"),
            swLon: Number(params.get("sw_lon") ?? "0"),
            operator: (params.get("operator") ?? "MILITARY_OPERATOR_UNSPECIFIED") as MilitaryOperator,
            aircraftType: (params.get("aircraft_type") ?? "MILITARY_AIRCRAFT_TYPE_UNSPECIFIED") as MilitaryAircraftType,
          };
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("listMilitaryFlights", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.listMilitaryFlights(ctx, body);
          return new Response(JSON.stringify(result as ListMilitaryFlightsResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/military/v1/get-theater-posture",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const url = new URL(req.url, "http://localhost");
          const params = url.searchParams;
          const body: GetTheaterPostureRequest = {
            theater: params.get("theater") ?? "",
          };
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("getTheaterPosture", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getTheaterPosture(ctx, body);
          return new Response(JSON.stringify(result as GetTheaterPostureResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/military/v1/get-aircraft-details",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const url = new URL(req.url, "http://localhost");
          const params = url.searchParams;
          const body: GetAircraftDetailsRequest = {
            icao24: params.get("icao24") ?? "",
          };
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("getAircraftDetails", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getAircraftDetails(ctx, body);
          return new Response(JSON.stringify(result as GetAircraftDetailsResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "POST",
      path: "/api/military/v1/get-aircraft-details-batch",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const body = await req.json() as GetAircraftDetailsBatchRequest;
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("getAircraftDetailsBatch", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getAircraftDetailsBatch(ctx, body);
          return new Response(JSON.stringify(result as GetAircraftDetailsBatchResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/military/v1/get-wingbits-status",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const body = {} as GetWingbitsStatusRequest;

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getWingbitsStatus(ctx, body);
          return new Response(JSON.stringify(result as GetWingbitsStatusResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/military/v1/get-usni-fleet-report",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const url = new URL(req.url, "http://localhost");
          const params = url.searchParams;
          const body: GetUSNIFleetReportRequest = {
            forceRefresh: params.get("force_refresh") === "true",
          };
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("getUSNIFleetReport", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getUSNIFleetReport(ctx, body);
          return new Response(JSON.stringify(result as GetUSNIFleetReportResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/military/v1/list-military-bases",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const url = new URL(req.url, "http://localhost");
          const params = url.searchParams;
          const body: ListMilitaryBasesRequest = {
            neLat: Number(params.get("ne_lat") ?? "0"),
            neLon: Number(params.get("ne_lon") ?? "0"),
            swLat: Number(params.get("sw_lat") ?? "0"),
            swLon: Number(params.get("sw_lon") ?? "0"),
            zoom: Number(params.get("zoom") ?? "0"),
            type: params.get("type") ?? "",
            kind: params.get("kind") ?? "",
            country: params.get("country") ?? "",
          };
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("listMilitaryBases", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.listMilitaryBases(ctx, body);
          return new Response(JSON.stringify(result as ListMilitaryBasesResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/military/v1/get-wingbits-live-flight",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const url = new URL(req.url, "http://localhost");
          const params = url.searchParams;
          const body: GetWingbitsLiveFlightRequest = {
            icao24: params.get("icao24") ?? "",
          };
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("getWingbitsLiveFlight", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getWingbitsLiveFlight(ctx, body);
          return new Response(JSON.stringify(result as GetWingbitsLiveFlightResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/military/v1/list-defense-patents",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const url = new URL(req.url, "http://localhost");
          const params = url.searchParams;
          const body: ListDefensePatentsRequest = {
            cpcCode: params.get("cpc_code") ?? "",
            assignee: params.get("assignee") ?? "",
            limit: Number(params.get("limit") ?? "0"),
          };
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("listDefensePatents", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.listDefensePatents(ctx, body);
          return new Response(JSON.stringify(result as ListDefensePatentsResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
  ];
}

