// Copyright 2022 Luca Casonato. All rights reserved. MIT license.
/**
 * Firebase Crashlytics API Client for Deno
 * ========================================
 * 
 * This service provides an API for mobile app developers to request deletion of user's crash reports.
 * 
 * Docs: https://firebase.google.com/docs/crashlytics
 * Source: https://googleapis.deno.dev/v1/firebasecrashlytics:v1alpha.ts
 */

import { auth, CredentialsClient, GoogleAuth, request } from "/_/base@v1/mod.ts";
export { auth, GoogleAuth };
export type { CredentialsClient };

/**
 * This service provides an API for mobile app developers to request deletion
 * of user's crash reports.
 */
export class FirebaseCrashlytics {
  #client: CredentialsClient | undefined;
  #baseUrl: string;

  constructor(client?: CredentialsClient, baseUrl: string = "https://firebasecrashlytics.googleapis.com/") {
    this.#client = client;
    this.#baseUrl = baseUrl;
  }

  /**
   * Fetch a batch of up to 100 events by name.
   *
   * @param parent Required. The firebase application. Format: "projects/{project}/apps/{app_id}".
   */
  async projectsAppsEventsBatchGet(parent: string, opts: ProjectsAppsEventsBatchGetOptions = {}): Promise<BatchGetEventsResponse> {
    opts = serializeProjectsAppsEventsBatchGetOptions(opts);
    const url = new URL(`${this.#baseUrl}v1alpha/${ parent }/events:batchGet`);
    if (opts.names !== undefined) {
      url.searchParams.append("names", String(opts.names));
    }
    if (opts.readMask !== undefined) {
      url.searchParams.append("readMask", String(opts.readMask));
    }
    const data = await request(url.href, {
      client: this.#client,
      method: "GET",
    });
    return deserializeBatchGetEventsResponse(data);
  }

  /**
   * List the events for an issue matching filter criteria, sorted in
   * descending order by timestamp.
   *
   * @param parent Required. The Firebase application. Format: "projects/{project}/apps/{app_id}".
   */
  async projectsAppsEventsList(parent: string, opts: ProjectsAppsEventsListOptions = {}): Promise<ListEventsResponse> {
    opts = serializeProjectsAppsEventsListOptions(opts);
    const url = new URL(`${this.#baseUrl}v1alpha/${ parent }/events`);
    if (opts["filter.browser.displayNames"] !== undefined) {
      url.searchParams.append("filter.browser.displayNames", String(opts["filter.browser.displayNames"]));
    }
    if (opts["filter.device.displayNames"] !== undefined) {
      url.searchParams.append("filter.device.displayNames", String(opts["filter.device.displayNames"]));
    }
    if (opts["filter.device.formFactors"] !== undefined) {
      url.searchParams.append("filter.device.formFactors", String(opts["filter.device.formFactors"]));
    }
    if (opts["filter.interval.endTime"] !== undefined) {
      url.searchParams.append("filter.interval.endTime", String(opts["filter.interval.endTime"]));
    }
    if (opts["filter.interval.startTime"] !== undefined) {
      url.searchParams.append("filter.interval.startTime", String(opts["filter.interval.startTime"]));
    }
    if (opts["filter.issue.content"] !== undefined) {
      url.searchParams.append("filter.issue.content", String(opts["filter.issue.content"]));
    }
    if (opts["filter.issue.errorTypes"] !== undefined) {
      url.searchParams.append("filter.issue.errorTypes", String(opts["filter.issue.errorTypes"]));
    }
    if (opts["filter.issue.id"] !== undefined) {
      url.searchParams.append("filter.issue.id", String(opts["filter.issue.id"]));
    }
    if (opts["filter.issue.signals"] !== undefined) {
      url.searchParams.append("filter.issue.signals", String(opts["filter.issue.signals"]));
    }
    if (opts["filter.issue.state"] !== undefined) {
      url.searchParams.append("filter.issue.state", String(opts["filter.issue.state"]));
    }
    if (opts["filter.issue.states"] !== undefined) {
      url.searchParams.append("filter.issue.states", String(opts["filter.issue.states"]));
    }
    if (opts["filter.issue.variantId"] !== undefined) {
      url.searchParams.append("filter.issue.variantId", String(opts["filter.issue.variantId"]));
    }
    if (opts["filter.operatingSystem.displayNames"] !== undefined) {
      url.searchParams.append("filter.operatingSystem.displayNames", String(opts["filter.operatingSystem.displayNames"]));
    }
    if (opts["filter.version.displayNames"] !== undefined) {
      url.searchParams.append("filter.version.displayNames", String(opts["filter.version.displayNames"]));
    }
    if (opts.pageSize !== undefined) {
      url.searchParams.append("pageSize", String(opts.pageSize));
    }
    if (opts.pageToken !== undefined) {
      url.searchParams.append("pageToken", String(opts.pageToken));
    }
    if (opts.readMask !== undefined) {
      url.searchParams.append("readMask", String(opts.readMask));
    }
    const data = await request(url.href, {
      client: this.#client,
      method: "GET",
    });
    return deserializeListEventsResponse(data);
  }

  /**
   * Change the state of a group of issues. This method is not atomic, so
   * partial failures can occur. In the event of a partial failure, the request
   * will fail and you will need to call `GetIssue` to see which issues were not
   * updated.
   *
   * @param parent Required. The parent resource shared by all issues being updated. Format: projects/{project}/apps/{app}. If this is set, the parent field in the UpdateIssueRequest messages must either be empty or match this field.
   */
  async projectsAppsIssuesBatchUpdate(parent: string, req: BatchUpdateIssuesRequest): Promise<BatchUpdateIssuesResponse> {
    req = serializeBatchUpdateIssuesRequest(req);
    const url = new URL(`${this.#baseUrl}v1alpha/${ parent }/issues:batchUpdate`);
    const body = JSON.stringify(req);
    const data = await request(url.href, {
      client: this.#client,
      method: "POST",
      body,
    });
    return data as BatchUpdateIssuesResponse;
  }

  /**
   * Retrieve an issue.
   *
   * @param name Required. The name of the issue to retrieve. Format: "projects/{project}/apps/{app}/issues/{issue}".
   */
  async projectsAppsIssuesGet(name: string): Promise<Issue> {
    const url = new URL(`${this.#baseUrl}v1alpha/${ name }`);
    const data = await request(url.href, {
      client: this.#client,
      method: "GET",
    });
    return data as Issue;
  }

  /**
   * Create a new note for an issue.
   *
   * @param parent Required. The parent resource where this note will be created. Format: "projects/{project}/apps/{app}/issues/{issue}".
   */
  async projectsAppsIssuesNotesCreate(parent: string, req: Note): Promise<Note> {
    const url = new URL(`${this.#baseUrl}v1alpha/${ parent }/notes`);
    const body = JSON.stringify(req);
    const data = await request(url.href, {
      client: this.#client,
      method: "POST",
      body,
    });
    return data as Note;
  }

  /**
   * Delete a note by its name.
   *
   * @param name Required. The name of the note to delete. Format: projects/{project}/apps/{app}/issues/{issue}/notes/{note}.
   */
  async projectsAppsIssuesNotesDelete(name: string): Promise<Empty> {
    const url = new URL(`${this.#baseUrl}v1alpha/${ name }`);
    const data = await request(url.href, {
      client: this.#client,
      method: "DELETE",
    });
    return data as Empty;
  }

  /**
   * List all notes for a certain issue, sorted in descending order by
   * timestamp.
   *
   * @param parent Required. The issue the notes belongs to. Format: "projects/{project}/apps/{app}/issues/{issue}".
   */
  async projectsAppsIssuesNotesList(parent: string, opts: ProjectsAppsIssuesNotesListOptions = {}): Promise<ListNotesResponse> {
    const url = new URL(`${this.#baseUrl}v1alpha/${ parent }/notes`);
    if (opts.pageSize !== undefined) {
      url.searchParams.append("pageSize", String(opts.pageSize));
    }
    if (opts.pageToken !== undefined) {
      url.searchParams.append("pageToken", String(opts.pageToken));
    }
    const data = await request(url.href, {
      client: this.#client,
      method: "GET",
    });
    return data as ListNotesResponse;
  }

  /**
   * Change the state of an issue.
   *
   * @param name Required. Output only. Immutable. Identifier. The name of the issue resource. Format: "projects/{project}/apps/{app}/issues/{issue}".
   */
  async projectsAppsIssuesPatch(name: string, req: Issue, opts: ProjectsAppsIssuesPatchOptions = {}): Promise<Issue> {
    opts = serializeProjectsAppsIssuesPatchOptions(opts);
    const url = new URL(`${this.#baseUrl}v1alpha/${ name }`);
    if (opts.updateMask !== undefined) {
      url.searchParams.append("updateMask", String(opts.updateMask));
    }
    const body = JSON.stringify(req);
    const data = await request(url.href, {
      client: this.#client,
      method: "PATCH",
      body,
    });
    return data as Issue;
  }

  /**
   * Get a report with its computed results.
   *
   * @param name Required. The report name. Format: "projects/{project}/apps/{app_id}/reports/{report}".
   */
  async projectsAppsReportsGet(name: string, opts: ProjectsAppsReportsGetOptions = {}): Promise<Report> {
    opts = serializeProjectsAppsReportsGetOptions(opts);
    const url = new URL(`${this.#baseUrl}v1alpha/${ name }`);
    if (opts["filter.browser.displayNames"] !== undefined) {
      url.searchParams.append("filter.browser.displayNames", String(opts["filter.browser.displayNames"]));
    }
    if (opts["filter.device.displayNames"] !== undefined) {
      url.searchParams.append("filter.device.displayNames", String(opts["filter.device.displayNames"]));
    }
    if (opts["filter.device.formFactors"] !== undefined) {
      url.searchParams.append("filter.device.formFactors", String(opts["filter.device.formFactors"]));
    }
    if (opts["filter.interval.endTime"] !== undefined) {
      url.searchParams.append("filter.interval.endTime", String(opts["filter.interval.endTime"]));
    }
    if (opts["filter.interval.startTime"] !== undefined) {
      url.searchParams.append("filter.interval.startTime", String(opts["filter.interval.startTime"]));
    }
    if (opts["filter.issue.content"] !== undefined) {
      url.searchParams.append("filter.issue.content", String(opts["filter.issue.content"]));
    }
    if (opts["filter.issue.errorTypes"] !== undefined) {
      url.searchParams.append("filter.issue.errorTypes", String(opts["filter.issue.errorTypes"]));
    }
    if (opts["filter.issue.id"] !== undefined) {
      url.searchParams.append("filter.issue.id", String(opts["filter.issue.id"]));
    }
    if (opts["filter.issue.signals"] !== undefined) {
      url.searchParams.append("filter.issue.signals", String(opts["filter.issue.signals"]));
    }
    if (opts["filter.issue.state"] !== undefined) {
      url.searchParams.append("filter.issue.state", String(opts["filter.issue.state"]));
    }
    if (opts["filter.issue.states"] !== undefined) {
      url.searchParams.append("filter.issue.states", String(opts["filter.issue.states"]));
    }
    if (opts["filter.issue.variantId"] !== undefined) {
      url.searchParams.append("filter.issue.variantId", String(opts["filter.issue.variantId"]));
    }
    if (opts["filter.operatingSystem.displayNames"] !== undefined) {
      url.searchParams.append("filter.operatingSystem.displayNames", String(opts["filter.operatingSystem.displayNames"]));
    }
    if (opts["filter.version.displayNames"] !== undefined) {
      url.searchParams.append("filter.version.displayNames", String(opts["filter.version.displayNames"]));
    }
    if (opts.granularity !== undefined) {
      url.searchParams.append("granularity", String(opts.granularity));
    }
    if (opts.pageSize !== undefined) {
      url.searchParams.append("pageSize", String(opts.pageSize));
    }
    if (opts.pageToken !== undefined) {
      url.searchParams.append("pageToken", String(opts.pageToken));
    }
    const data = await request(url.href, {
      client: this.#client,
      method: "GET",
    });
    return deserializeReport(data);
  }

  /**
   * List all of the available reports.
   *
   * @param parent Required. The firebase application. Format: "projects/{project}/apps/{app_id}".
   */
  async projectsAppsReportsList(parent: string): Promise<ListReportsResponse> {
    const url = new URL(`${this.#baseUrl}v1alpha/${ parent }/reports`);
    const data = await request(url.href, {
      client: this.#client,
      method: "GET",
    });
    return deserializeListReportsResponse(data);
  }

  /**
   * Enqueues a request to permanently remove crash reports associated with the
   * specified user. All reports belonging to the specified user will be deleted
   * typically within 24 hours of receiving the crash report.
   *
   * @param name Required. Resource name for user reports, in the format: projects/ PROJECT_IDENTIFIER/apps/APP_ID/users/USER_ID/crashReports - PROJECT_IDENTIFIER: The Firebase project's project number (recommended) or its project ID. Learn more about using project identifiers in Google's [AIP 2510 standard](https://google.aip.dev/cloud/2510). - APP_ID: The globally unique, Firebase-assigned identifier for the Firebase App. This is not your package name or bundle ID. Learn how to [find your app ID](https://firebase.google.com/support/faq/#find-app-id). - USER_ID: The user ID set using the Crashlytics SDK. Learn how to [set user identifiers](https://firebase.google.com/docs/crashlytics/customize-crash-reports#set-user-ids).
   */
  async projectsAppsUsersDeleteCrashReports(name: string): Promise<DeleteUserCrashReportsResponse> {
    const url = new URL(`${this.#baseUrl}v1alpha/${ name }`);
    const data = await request(url.href, {
      client: this.#client,
      method: "DELETE",
    });
    return deserializeDeleteUserCrashReportsResponse(data);
  }
}

/**
 * Response message for the BatchGetEvents method.
 */
export interface BatchGetEventsResponse {
  /**
   * The list of retrieved events.
   */
  events?: Event[];
}

function serializeBatchGetEventsResponse(data: any): BatchGetEventsResponse {
  return {
    ...data,
    events: data["events"] !== undefined ? data["events"].map((item: any) => (serializeEvent(item))) : undefined,
  };
}

function deserializeBatchGetEventsResponse(data: any): BatchGetEventsResponse {
  return {
    ...data,
    events: data["events"] !== undefined ? data["events"].map((item: any) => (deserializeEvent(item))) : undefined,
  };
}

/**
 * Request message for the BatchUpdateIssues method.
 */
export interface BatchUpdateIssuesRequest {
  /**
   * Required. The request message specifying the resources to update. A
   * maximum of 100 issues can be modified in a batch.
   */
  requests?: UpdateIssueRequest[];
  /**
   * Optional. The list of Issue fields to update. If this is set, the
   * update_mask field in the UpdateIssueRequest messages must either be empty
   * or match this field.
   */
  updateMask?: string /* FieldMask */;
}

function serializeBatchUpdateIssuesRequest(data: any): BatchUpdateIssuesRequest {
  return {
    ...data,
    requests: data["requests"] !== undefined ? data["requests"].map((item: any) => (serializeUpdateIssueRequest(item))) : undefined,
    updateMask: data["updateMask"] !== undefined ? data["updateMask"] : undefined,
  };
}

function deserializeBatchUpdateIssuesRequest(data: any): BatchUpdateIssuesRequest {
  return {
    ...data,
    requests: data["requests"] !== undefined ? data["requests"].map((item: any) => (deserializeUpdateIssueRequest(item))) : undefined,
    updateMask: data["updateMask"] !== undefined ? data["updateMask"] : undefined,
  };
}

/**
 * Response message for the BatchUpdateIssues method.
 */
export interface BatchUpdateIssuesResponse {
  /**
   * Issues updated in the same order as in BatchUpdateIssuesRequest.
   */
  issues?: Issue[];
}

/**
 * Analytics events recorded during the session.
 */
export interface Breadcrumb {
  /**
   * Device timestamp for the event.
   */
  eventTime?: Date;
  /**
   * Event parameters.
   */
  params?: {
    [key: string]: string
  };
  /**
   * Analytic event name.
   */
  title?: string;
}

function serializeBreadcrumb(data: any): Breadcrumb {
  return {
    ...data,
    eventTime: data["eventTime"] !== undefined ? data["eventTime"].toISOString() : undefined,
  };
}

function deserializeBreadcrumb(data: any): Breadcrumb {
  return {
    ...data,
    eventTime: data["eventTime"] !== undefined ? new Date(data["eventTime"]) : undefined,
  };
}

/**
 * Web browser metadata.
 */
export interface Browser {
  /**
   * Browser name.
   */
  browser?: string;
  /**
   * Browser name and version number. Formatted to be suitable for passing to
   * BrowserFilter.
   */
  displayName?: string;
  /**
   * Browser display version number.
   */
  displayVersion?: string;
}

/**
 * Response message for the DeleteUserCrashReports method. All crash reports
 * associated with the specified user will be deleted typically within 24 hours
 * of receiving the crash report.
 */
export interface DeleteUserCrashReportsResponse {
  /**
   * Target time to complete the delete crash reports operation.
   */
  targetCompleteTime?: Date;
}

function serializeDeleteUserCrashReportsResponse(data: any): DeleteUserCrashReportsResponse {
  return {
    ...data,
    targetCompleteTime: data["targetCompleteTime"] !== undefined ? data["targetCompleteTime"].toISOString() : undefined,
  };
}

function deserializeDeleteUserCrashReportsResponse(data: any): DeleteUserCrashReportsResponse {
  return {
    ...data,
    targetCompleteTime: data["targetCompleteTime"] !== undefined ? new Date(data["targetCompleteTime"]) : undefined,
  };
}

/**
 * Mobile device metadata.
 */
export interface Device {
  /**
   * Device processor architecture.
   */
  architecture?: string;
  /**
   * An invariant name of the manufacturer that submitted this product in its
   * most recognizable public form, e.g. "Google".
   */
  companyName?: string;
  /**
   * Full device name, suitable for passing to DeviceFilter. Format:
   * "manufacturer (model)".
   */
  displayName?: string;
  /**
   * See FormFactor message.
   */
  formFactor?:  | "FORM_FACTOR_UNSPECIFIED" | "PHONE" | "TABLET" | "DESKTOP" | "TV" | "WATCH";
  /**
   * Device brand name which is consistent with android.os.Build.BRAND.
   */
  manufacturer?: string;
  /**
   * Marketing name, most recognizable public form, e.g. "Pixel 6".
   */
  marketingName?: string;
  /**
   * The model name which is consistent with android.os.Build.MODEL, e.g.
   * ("SPH-L710", "GT-I9300").
   */
  model?: string;
}

/**
 * A generic empty message that you can re-use to avoid defining duplicated
 * empty messages in your APIs. A typical example is to use it as the request or
 * the response type of an API method. For instance: service Foo { rpc
 * Bar(google.protobuf.Empty) returns (google.protobuf.Empty); }
 */
export interface Empty {
}

/**
 * A non-fatal error and its stacktrace, only from Apple apps.
 */
export interface Error {
  /**
   * True when the Crashlytics analysis has determined that the stacktrace in
   * this error is where the fault occurred.
   */
  blamed?: boolean;
  /**
   * Error code associated with the app's custom logged NSError.
   */
  code?: bigint;
  /**
   * The frames in the error's stacktrace.
   */
  frames?: Frame[];
  /**
   * The queue on which the thread was running.
   */
  queue?: string;
  /**
   * The subtitle of the error.
   */
  subtitle?: string;
  /**
   * The title of the error.
   */
  title?: string;
}

function serializeError(data: any): Error {
  return {
    ...data,
    code: data["code"] !== undefined ? String(data["code"]) : undefined,
    frames: data["frames"] !== undefined ? data["frames"].map((item: any) => (serializeFrame(item))) : undefined,
  };
}

function deserializeError(data: any): Error {
  return {
    ...data,
    code: data["code"] !== undefined ? BigInt(data["code"]) : undefined,
    frames: data["frames"] !== undefined ? data["frames"].map((item: any) => (deserializeFrame(item))) : undefined,
  };
}

/**
 * The message describing a single Crashlytics event. Related to BigQuery
 * export schema, which can be found at [Export Crashlytics data to
 * BigQuery](https://firebase.google.com/docs/crashlytics/bigquery-export#dataset-schema-crashlytics)
 */
export interface Event {
  /**
   * App orientation at the time of the crash (portrait or landscape).
   */
  appOrientation?: string;
  /**
   * The stack trace frame blamed by Crashlytics processing. May not be present
   * in future analyzer.
   */
  blameFrame?: Frame;
  /**
   * Analytics events recorded by the analytics SDK during the session.
   */
  breadcrumbs?: Breadcrumb[];
  /**
   * Browser and version.
   */
  browser?: Browser;
  /**
   * Metadata provided by the app's build system, including version control
   * repository info.
   */
  buildStamp?: string;
  /**
   * The bundle name for iOS apps or the package name of Android apps. Format:
   * "com.mycompany.myapp".
   */
  bundleOrPackage?: string;
  /**
   * Crashlytics SDK version.
   */
  crashlyticsSdkVersion?: string;
  /**
   * Custom keys set by the developer during the session.
   */
  customKeys?: {
    [key: string]: string
  };
  /**
   * Mobile device metadata.
   */
  device?: Device;
  /**
   * Device orientation at the time of the crash (portrait or landscape).
   */
  deviceOrientation?: string;
  /**
   * Apple only. A non-fatal error captured by the iOS SDK and its stacktrace.
   */
  errors?: Error[];
  /**
   * Output only. Immutable. The unique event identifier is assigned during
   * processing.
   */
  readonly eventId?: string;
  /**
   * Device timestamp that the event was recorded.
   */
  eventTime?: Date;
  /**
   * Android and web only. Exceptions that occurred during this event. Nested
   * exceptions are presented in reverse chronological order, so that the last
   * record is the first exception thrown.
   */
  exceptions?: Exception[];
  /**
   * Unique identifier for the device-app installation. This field is used to
   * compute the unique number of impacted users.
   */
  installationUuid?: string;
  /**
   * Details for the [Issue] assigned to this [Event].
   */
  issue?: Issue;
  /**
   * The subtitle of the issue in which the event was grouped. This is usually
   * a symbol or an exception message.
   */
  issueSubtitle?: string;
  /**
   * The title of the issue in which the event was grouped. This is usually a
   * source file or method name.
   */
  issueTitle?: string;
  /**
   * Details for the [IssueVariant] assigned to this [Event].
   */
  issueVariant?: IssueVariant;
  /**
   * Log messages recorded by the developer during the session.
   */
  logs?: Log[];
  /**
   * Mobile device memory usage.
   */
  memory?: Memory;
  /**
   * Required. Output only. Immutable. Identifier. The name of the event
   * resource. Format: "projects/{project}/apps/{app_id}/events/{event}".
   */
  readonly name?: string;
  /**
   * Operating system and version.
   */
  operatingSystem?: OperatingSystem;
  /**
   * ANDROID, IOS, or WEB.
   */
  platform?: string;
  /**
   * The state of the app process at the time of the event.
   */
  processState?: string;
  /**
   * Server timestamp that the event was received by Crashlytics.
   */
  receivedTime?: Date;
  /**
   * Output only. Web only. The route path of the web application when the
   * event occurred, excluding query parameters and fragment.
   */
  readonly routePath?: string;
  /**
   * Unique identifier for the Firebase session.
   */
  sessionId?: string;
  /**
   * Mobile device disk/flash usage.
   */
  storage?: Storage;
  /**
   * Application threads present at the time the event was recorded. Each
   * contains a stacktrace. One thread will be blamed for the error.
   */
  threads?: Thread[];
  /**
   * End user identifiers for the device owner.
   */
  user?: User;
  /**
   * Mobile application version.
   */
  version?: Version;
}

function serializeEvent(data: any): Event {
  return {
    ...data,
    blameFrame: data["blameFrame"] !== undefined ? serializeFrame(data["blameFrame"]) : undefined,
    breadcrumbs: data["breadcrumbs"] !== undefined ? data["breadcrumbs"].map((item: any) => (serializeBreadcrumb(item))) : undefined,
    errors: data["errors"] !== undefined ? data["errors"].map((item: any) => (serializeError(item))) : undefined,
    eventTime: data["eventTime"] !== undefined ? data["eventTime"].toISOString() : undefined,
    exceptions: data["exceptions"] !== undefined ? data["exceptions"].map((item: any) => (serializeException(item))) : undefined,
    logs: data["logs"] !== undefined ? data["logs"].map((item: any) => (serializeLog(item))) : undefined,
    memory: data["memory"] !== undefined ? serializeMemory(data["memory"]) : undefined,
    receivedTime: data["receivedTime"] !== undefined ? data["receivedTime"].toISOString() : undefined,
    storage: data["storage"] !== undefined ? serializeStorage(data["storage"]) : undefined,
    threads: data["threads"] !== undefined ? data["threads"].map((item: any) => (serializeThread(item))) : undefined,
  };
}

function deserializeEvent(data: any): Event {
  return {
    ...data,
    blameFrame: data["blameFrame"] !== undefined ? deserializeFrame(data["blameFrame"]) : undefined,
    breadcrumbs: data["breadcrumbs"] !== undefined ? data["breadcrumbs"].map((item: any) => (deserializeBreadcrumb(item))) : undefined,
    errors: data["errors"] !== undefined ? data["errors"].map((item: any) => (deserializeError(item))) : undefined,
    eventTime: data["eventTime"] !== undefined ? new Date(data["eventTime"]) : undefined,
    exceptions: data["exceptions"] !== undefined ? data["exceptions"].map((item: any) => (deserializeException(item))) : undefined,
    logs: data["logs"] !== undefined ? data["logs"].map((item: any) => (deserializeLog(item))) : undefined,
    memory: data["memory"] !== undefined ? deserializeMemory(data["memory"]) : undefined,
    receivedTime: data["receivedTime"] !== undefined ? new Date(data["receivedTime"]) : undefined,
    storage: data["storage"] !== undefined ? deserializeStorage(data["storage"]) : undefined,
    threads: data["threads"] !== undefined ? data["threads"].map((item: any) => (deserializeThread(item))) : undefined,
  };
}

/**
 * A Java or Javascript exception and its stacktrace. Only from Android or web
 * apps.
 */
export interface Exception {
  /**
   * True when the Crashlytics analysis has determined that this thread is
   * where the fault occurred.
   */
  blamed?: boolean;
  /**
   * A message associated with the exception.
   */
  exceptionMessage?: string;
  /**
   * The frames in the exception's stacktrace.
   */
  frames?: Frame[];
  /**
   * True for all but the last-thrown exception (i.e. the first record).
   */
  nested?: boolean;
  /**
   * The subtitle of the exception.
   */
  subtitle?: string;
  /**
   * The title of the exception.
   */
  title?: string;
  /**
   * The exception type e.g. java.lang.IllegalStateException.
   */
  type?: string;
}

function serializeException(data: any): Exception {
  return {
    ...data,
    frames: data["frames"] !== undefined ? data["frames"].map((item: any) => (serializeFrame(item))) : undefined,
  };
}

function deserializeException(data: any): Exception {
  return {
    ...data,
    frames: data["frames"] !== undefined ? data["frames"].map((item: any) => (deserializeFrame(item))) : undefined,
  };
}

/**
 * Sessions recorded by the Firebase App Quality Sessions SDK.
 */
export interface FirebaseSessionEvent {
  /**
   * Mobile device metadata.
   */
  device?: Device;
  /**
   * The start timestamp for the session event.
   */
  eventTime?: Date;
  /**
   * Session event type. The SDK only supports SESSION_START events at this
   * time.
   */
  eventType?:  | "SESSION_EVENT_TYPE_UNKNOWN" | "SESSION_START";
  /**
   * Uniquely identifies a device with Firebase apps installed.
   */
  firebaseInstallationId?: string;
  /**
   * The identifier of the first session since the last cold start. This id and
   * the session_id will be the same for app launches.
   */
  firstSessionId?: string;
  /**
   * Operating system and version.
   */
  operatingSystem?: OperatingSystem;
  /**
   * Unique identifier for the Firebase session.
   */
  sessionId?: string;
  /**
   * Indicates the number of sessions since the last cold start.
   */
  sessionIndex?: number;
  /**
   * Mobile application version numbers.
   */
  version?: Version;
}

function serializeFirebaseSessionEvent(data: any): FirebaseSessionEvent {
  return {
    ...data,
    eventTime: data["eventTime"] !== undefined ? data["eventTime"].toISOString() : undefined,
  };
}

function deserializeFirebaseSessionEvent(data: any): FirebaseSessionEvent {
  return {
    ...data,
    eventTime: data["eventTime"] !== undefined ? new Date(data["eventTime"]) : undefined,
  };
}

/**
 * A frame in a stacktrace.
 */
export interface Frame {
  /**
   * The address in the binary image which contains the code. Present for
   * native frames.
   */
  address?: bigint;
  /**
   * True when the Crashlytics analysis has determined that this frame is
   * likely to be the cause of the error.
   */
  blamed?: boolean;
  /**
   * The column on the line.
   */
  column?: bigint;
  /**
   * The name of the source file in which the frame is found.
   */
  file?: string;
  /**
   * The display name of the library that includes the frame.
   */
  library?: string;
  /**
   * The line number in the file of the frame.
   */
  line?: bigint;
  /**
   * The byte offset into the binary image that contains the code. Present for
   * native frames.
   */
  offset?: bigint;
  /**
   * One of DEVELOPER, VENDOR, RUNTIME, PLATFORM, or SYSTEM.
   */
  owner?: string;
  /**
   * The frame symbol after it has been deobfuscated or symbolicated. The raw
   * symbol from the device if it could not be hydrated.
   */
  symbol?: string;
}

function serializeFrame(data: any): Frame {
  return {
    ...data,
    address: data["address"] !== undefined ? String(data["address"]) : undefined,
    column: data["column"] !== undefined ? String(data["column"]) : undefined,
    line: data["line"] !== undefined ? String(data["line"]) : undefined,
    offset: data["offset"] !== undefined ? String(data["offset"]) : undefined,
  };
}

function deserializeFrame(data: any): Frame {
  return {
    ...data,
    address: data["address"] !== undefined ? BigInt(data["address"]) : undefined,
    column: data["column"] !== undefined ? BigInt(data["column"]) : undefined,
    line: data["line"] !== undefined ? BigInt(data["line"]) : undefined,
    offset: data["offset"] !== undefined ? BigInt(data["offset"]) : undefined,
  };
}

/**
 * A set of computed metric values for a time interval
 */
export interface IntervalMetrics {
  /**
   * The end of the interval covered by the computation.
   */
  endTime?: Date;
  /**
   * The total count of events in the interval.
   */
  eventsCount?: bigint;
  /**
   * The number of distinct users in the set of events.
   */
  impactedUsersCount?: bigint;
  /**
   * The number of distinct sessions in the set of events.
   */
  sessionsCount?: bigint;
  /**
   * The start of the interval covered by the computation.
   */
  startTime?: Date;
}

function serializeIntervalMetrics(data: any): IntervalMetrics {
  return {
    ...data,
    endTime: data["endTime"] !== undefined ? data["endTime"].toISOString() : undefined,
    eventsCount: data["eventsCount"] !== undefined ? String(data["eventsCount"]) : undefined,
    impactedUsersCount: data["impactedUsersCount"] !== undefined ? String(data["impactedUsersCount"]) : undefined,
    sessionsCount: data["sessionsCount"] !== undefined ? String(data["sessionsCount"]) : undefined,
    startTime: data["startTime"] !== undefined ? data["startTime"].toISOString() : undefined,
  };
}

function deserializeIntervalMetrics(data: any): IntervalMetrics {
  return {
    ...data,
    endTime: data["endTime"] !== undefined ? new Date(data["endTime"]) : undefined,
    eventsCount: data["eventsCount"] !== undefined ? BigInt(data["eventsCount"]) : undefined,
    impactedUsersCount: data["impactedUsersCount"] !== undefined ? BigInt(data["impactedUsersCount"]) : undefined,
    sessionsCount: data["sessionsCount"] !== undefined ? BigInt(data["sessionsCount"]) : undefined,
    startTime: data["startTime"] !== undefined ? new Date(data["startTime"]) : undefined,
  };
}

/**
 * An issue describes a set of similar events that have been analyzed by
 * Crashlytics and grouped together. All events within an issue will be of the
 * same error_type: crash, non-fatal exception or ANR. All events within an
 * issue will contain similar stack traces in their blamed thread.
 */
export interface Issue {
  /**
   * Output only. Immutable. Indicates whether this issue is a crash, non-fatal
   * exception, or ANR.
   */
  readonly errorType?:  | "ERROR_TYPE_UNSPECIFIED" | "FATAL" | "NON_FATAL" | "ANR";
  /**
   * Output only. Immutable. The first time this issue was seen.
   */
  readonly firstSeenTime?: Date;
  /**
   * Output only. Immutable. The first app display_version in which this issue
   * was seen, populated for mobile issues only.
   */
  readonly firstSeenVersion?: string;
  /**
   * Output only. Immutable. Unique identifier for the issue.
   */
  readonly id?: string;
  /**
   * Output only. The most recent time this issue was seen.
   */
  readonly lastSeenTime?: Date;
  /**
   * Output only. The most recent app display_version in which this issue was
   * seen, populated for mobile issues only.
   */
  readonly lastSeenVersion?: string;
  /**
   * Required. Output only. Immutable. Identifier. The name of the issue
   * resource. Format: "projects/{project}/apps/{app}/issues/{issue}".
   */
  readonly name?: string;
  /**
   * Output only. The number of notes attached to an issue.
   */
  readonly notesCount?: bigint;
  /**
   * Output only. The resource name for a sample event in this issue.
   */
  readonly sampleEvent?: string;
  /**
   * Output only. Immutable. Distinctive characteristics assigned by the
   * Crashlytics analyzer.
   */
  readonly signals?: IssueSignals[];
  /**
   * Output only. Indicates whether this issue is open, closed or muted. For
   * details on how issue states change without user actions, see [Regressed
   * Issues](https://firebase.google.com/docs/crashlytics/troubleshooting?platform=ios#regressed-issues).
   */
  readonly state?:  | "STATE_UNSPECIFIED" | "OPEN" | "CLOSED" | "MUTED";
  /**
   * Output only. The time at which the issue state was last changed.
   */
  readonly stateUpdateTime?: Date;
  /**
   * Output only. Immutable. Caption subtitle. This is usually a symbol or an
   * exception message.
   */
  readonly subtitle?: string;
  /**
   * Output only. Immutable. Caption title. This is usually a source file or
   * method name.
   */
  readonly title?: string;
  /**
   * Output only. Provides a link to the Issue on the Firebase console. When
   * this Issue is obtained as part of a Report, then the link will be
   * configured with the same time interval and filters as the request.
   */
  readonly uri?: string;
  /**
   * Output only. Immutable. The top 12 variants (subgroups) within the issue.
   * Variants group events within an issue that are very similar. A single
   * result implies that the variant is the same as the parent issue. This field
   * will be empty when multiple issues are requested. Request a single issue to
   * list variants.
   */
  readonly variants?: IssueVariant[];
}

/**
 * Distinctive characteristics assigned by the Crashlytics analyzer.
 */
export interface IssueSignals {
  /**
   * Output only. Supporting detail information.
   */
  readonly description?: string;
  /**
   * Output only. The signal name.
   */
  readonly signal?:  | "SIGNAL_UNSPECIFIED" | "SIGNAL_EARLY" | "SIGNAL_FRESH" | "SIGNAL_REGRESSED" | "SIGNAL_REPETITIVE";
}

/**
 * A variant is a subgroup of an issue where all events have very similar stack
 * traces. Issues may contain one or more variants.
 */
export interface IssueVariant {
  /**
   * Output only. Immutable. Distinct identifier for the variant.
   */
  readonly id?: string;
  /**
   * Output only. The resource name for a sample event in this variant.
   */
  readonly sampleEvent?: string;
  /**
   * Output only. Provides a link to the variant on the Firebase console. When
   * this variant is obtained as part of a Report, then the link will be
   * configured with the same time interval and filters as the request.
   */
  readonly uri?: string;
}

/**
 * Response message for the ListEvents method.
 */
export interface ListEventsResponse {
  /**
   * Returns one element per event, in descending order the by event timestamp.
   */
  events?: Event[];
  /**
   * A pagination token to retrieve the next page of events. The next page will
   * have earlier or later events depending on the request's ordering. If this
   * field is not present, there are no subsequent events.
   */
  nextPageToken?: string;
}

function serializeListEventsResponse(data: any): ListEventsResponse {
  return {
    ...data,
    events: data["events"] !== undefined ? data["events"].map((item: any) => (serializeEvent(item))) : undefined,
  };
}

function deserializeListEventsResponse(data: any): ListEventsResponse {
  return {
    ...data,
    events: data["events"] !== undefined ? data["events"].map((item: any) => (deserializeEvent(item))) : undefined,
  };
}

/**
 * Response message for the ListNotes method.
 */
export interface ListNotesResponse {
  /**
   * A pagination token to retrieve the next page of notes. If this field is
   * not present, there are no subsequent notes.
   */
  nextPageToken?: string;
  /**
   * Returns notes ordered descending by the timestamp.
   */
  notes?: Note[];
}

/**
 * Response method for the ListReports method. The response will always include
 * all of the available reports.
 */
export interface ListReportsResponse {
  /**
   * The report objects returned will contain their names and usage
   * instructions, but include no results. Use the `GetReport` method to run the
   * report and obtain the paged results.
   */
  reports?: Report[];
}

function serializeListReportsResponse(data: any): ListReportsResponse {
  return {
    ...data,
    reports: data["reports"] !== undefined ? data["reports"].map((item: any) => (serializeReport(item))) : undefined,
  };
}

function deserializeListReportsResponse(data: any): ListReportsResponse {
  return {
    ...data,
    reports: data["reports"] !== undefined ? data["reports"].map((item: any) => (deserializeReport(item))) : undefined,
  };
}

/**
 * Developer-provided log lines recorded during the session.
 */
export interface Log {
  /**
   * Device timestamp when the line was logged.
   */
  logTime?: Date;
  /**
   * Log message.
   */
  message?: string;
}

function serializeLog(data: any): Log {
  return {
    ...data,
    logTime: data["logTime"] !== undefined ? data["logTime"].toISOString() : undefined,
  };
}

function deserializeLog(data: any): Log {
  return {
    ...data,
    logTime: data["logTime"] !== undefined ? new Date(data["logTime"]) : undefined,
  };
}

/**
 * Mobile device memory usage.
 */
export interface Memory {
  /**
   * Bytes free.
   */
  free?: bigint;
  /**
   * Bytes in use.
   */
  used?: bigint;
}

function serializeMemory(data: any): Memory {
  return {
    ...data,
    free: data["free"] !== undefined ? String(data["free"]) : undefined,
    used: data["used"] !== undefined ? String(data["used"]) : undefined,
  };
}

function deserializeMemory(data: any): Memory {
  return {
    ...data,
    free: data["free"] !== undefined ? BigInt(data["free"]) : undefined,
    used: data["used"] !== undefined ? BigInt(data["used"]) : undefined,
  };
}

/**
 * Developer notes for an issue.
 */
export interface Note {
  /**
   * Output only. The email of the author of the note.
   */
  readonly author?: string;
  /**
   * Immutable. The body of the note.
   */
  body?: string;
  /**
   * Output only. Time when the note was created.
   */
  readonly createTime?: Date;
  /**
   * Output only. Identifier. Format:
   * "projects/{project}/apps/app/issues/{issue}/notes/{note}".
   */
  readonly name?: string;
}

/**
 * Mobile device operating system metadata.
 */
export interface OperatingSystem {
  /**
   * The device category (mobile, tablet, desktop).
   */
  deviceType?: string;
  /**
   * Name and version number. Formatted to be suitable for passing to
   * OperatingSystemFilter.
   */
  displayName?: string;
  /**
   * Operating system display version number.
   */
  displayVersion?: string;
  /**
   * Indicates if the OS has been modified or "jailbroken".
   */
  modificationState?: string;
  /**
   * Operating system name.
   */
  os?: string;
  /**
   * The OS type on Apple platforms (iOS, iPadOS, etc.).
   */
  type?: string;
}

/**
 * Describes a release track in the Play Developer Console.
 */
export interface PlayTrack {
  /**
   * User-generated or auto-generated name of the track. PROD and INTERNAL
   * track types always have auto-generated names, e.g. "prod" and "internal"
   * respectively. Tracks of type EARLY_ACCESS always have a user-generated
   * name. Other track types do not have any guarantees, might have
   * user-generated or auto-generated names.
   */
  title?: string;
  /**
   * The type of track (prod, internal, etc...).
   */
  type?:  | "TRACK_TYPE_UNSPECIFIED" | "TRACK_TYPE_PROD" | "TRACK_TYPE_INTERNAL" | "TRACK_TYPE_OPEN_TESTING" | "TRACK_TYPE_CLOSED_TESTING" | "TRACK_TYPE_EARLY_ACCESS";
}

/**
 * Additional options for FirebaseCrashlytics#projectsAppsEventsBatchGet.
 */
export interface ProjectsAppsEventsBatchGetOptions {
  /**
   * Required. The resource names of the desired events. A maximum of 100
   * events can be retrieved in a batch. Format:
   * "projects/{project}/apps/{app_id}/events/{event_id}". The app_id and
   * event_id are required, but project may be "-" to conserve space in long
   * URIs.
   */
  names?: string;
  /**
   * Optional. The list of Event fields to include in the response. If omitted,
   * the full event is returned.
   */
  readMask?: string /* FieldMask */;
}

function serializeProjectsAppsEventsBatchGetOptions(data: any): ProjectsAppsEventsBatchGetOptions {
  return {
    ...data,
    readMask: data["readMask"] !== undefined ? data["readMask"] : undefined,
  };
}

function deserializeProjectsAppsEventsBatchGetOptions(data: any): ProjectsAppsEventsBatchGetOptions {
  return {
    ...data,
    readMask: data["readMask"] !== undefined ? data["readMask"] : undefined,
  };
}

/**
 * Additional options for FirebaseCrashlytics#projectsAppsEventsList.
 */
export interface ProjectsAppsEventsListOptions {
  /**
   * Optional. Only count events from the given browser. This string matches
   * Browser.display_name. Format: "name (display_version)" e.g. "Chrome (123)",
   * or just "name" for all possible versions, e.g. simply "Chrome".
   */
  ["filter.browser.displayNames"]?: string;
  /**
   * Only counts events from the given Device model. This string matches
   * Device.display_name. Format: "manufacturer (model)" e.g. "Google (Pixel
   * 6)", or just "manufacturer" for all possible models, e.g. simply "Google".
   * Note that a device's marketing_name field can not be used for filtering.
   */
  ["filter.device.displayNames"]?: string;
  /**
   * Only counts events from devices with the given form factor (e.g. phone or
   * tablet).
   */
  ["filter.device.formFactors"]?:  | "FORM_FACTOR_UNSPECIFIED" | "PHONE" | "TABLET" | "DESKTOP" | "TV" | "WATCH";
  /**
   * Optional. Exclusive end of the interval. If specified, a Timestamp
   * matching this interval will have to be before the end.
   */
  ["filter.interval.endTime"]?: Date;
  /**
   * Optional. Inclusive start of the interval. If specified, a Timestamp
   * matching this interval will have to be the same or after the start.
   */
  ["filter.interval.startTime"]?: Date;
  /**
   * Optional. A space separated list of filter terms matched against the
   * contents of the issue. Contents include the title and the stack trace.
   * Matches must begin at alphanumeric tokens, i.e., 'util.Sorted' matches
   * 'java.util.SortedSet' but not 'myutil.SortedArray'. The filter matches if
   * all filter terms match. All non-alphanumeric characters are ignored for
   * matching. Filtering is assumed to be prefix-search and order-independent
   * unless phrases are surrounded by "". Any terms contained in quotes are
   * searched using exact-match (given filter term "foo", we will not return
   * "foobar"), and must appear in the order given exactly. To get
   * order-dependence but prefix-search, use a * within the quotes ("abc foo*"
   * will match "abc foobar", but not "foo abc" "abcd foobar", or "abc xyz
   * foobar").
   */
  ["filter.issue.content"]?: string;
  /**
   * Optional. Only counts events of the given error types. This field matches
   * [Issue.error_type].
   */
  ["filter.issue.errorTypes"]?:  | "ERROR_TYPE_UNSPECIFIED" | "FATAL" | "NON_FATAL" | "ANR";
  /**
   * Optional. Only counts events in the given issue ID. This field matches
   * [Issue.id].
   */
  ["filter.issue.id"]?: string;
  /**
   * Optional. Only returns issues currently marked with the given signals.
   * This field matches [Issue.signals.signal].
   */
  ["filter.issue.signals"]?:  | "SIGNAL_UNSPECIFIED" | "SIGNAL_EARLY" | "SIGNAL_FRESH" | "SIGNAL_REGRESSED" | "SIGNAL_REPETITIVE";
  /**
   * Optional. Deprecated: Prefer `states` field. Only includes events for
   * issues with the given issue state. Only available for `topIssues` reports.
   */
  ["filter.issue.state"]?:  | "STATE_UNSPECIFIED" | "OPEN" | "CLOSED" | "MUTED";
  /**
   * Optional. Only includes events for issues with the given issue states.
   * Only available for `topIssues` reports.
   */
  ["filter.issue.states"]?:  | "STATE_UNSPECIFIED" | "OPEN" | "CLOSED" | "MUTED";
  /**
   * Optional. Only counts events for the given issue variant ID. This field
   * matches [IssueVariant.id].
   */
  ["filter.issue.variantId"]?: string;
  /**
   * Only counts events in the given operating system and version. This string
   * matches OperatingSystem.display_name. Format: "osName (osVersion)" e.g.
   * "Android (11)". or just "osName" for all versions, e.g. simply "iPadOS".
   */
  ["filter.operatingSystem.displayNames"]?: string;
  /**
   * Only counts events in the given app version. This string matches
   * Version.display_name. Format: "display_version (build_version)" e.g. "1.2.3
   * (456)".
   */
  ["filter.version.displayNames"]?: string;
  /**
   * Optional. The maximum number of events per page. If omitted, defaults to
   * 10.
   */
  pageSize?: number;
  /**
   * Optional. A page token, received from a previous calls.
   */
  pageToken?: string;
  /**
   * Optional. The list of Event fields to include in the response. If omitted,
   * the full event is returned.
   */
  readMask?: string /* FieldMask */;
}

function serializeProjectsAppsEventsListOptions(data: any): ProjectsAppsEventsListOptions {
  return {
    ...data,
    ["filter.interval.endTime"]: data["filter.interval.endTime"] !== undefined ? data["filter.interval.endTime"].toISOString() : undefined,
    ["filter.interval.startTime"]: data["filter.interval.startTime"] !== undefined ? data["filter.interval.startTime"].toISOString() : undefined,
    readMask: data["readMask"] !== undefined ? data["readMask"] : undefined,
  };
}

function deserializeProjectsAppsEventsListOptions(data: any): ProjectsAppsEventsListOptions {
  return {
    ...data,
    ["filter.interval.endTime"]: data["filter.interval.endTime"] !== undefined ? new Date(data["filter.interval.endTime"]) : undefined,
    ["filter.interval.startTime"]: data["filter.interval.startTime"] !== undefined ? new Date(data["filter.interval.startTime"]) : undefined,
    readMask: data["readMask"] !== undefined ? data["readMask"] : undefined,
  };
}

/**
 * Additional options for FirebaseCrashlytics#projectsAppsIssuesNotesList.
 */
export interface ProjectsAppsIssuesNotesListOptions {
  /**
   * Optional. The maximum number of notes per page. If omitted, defaults to
   * 10.
   */
  pageSize?: number;
  /**
   * Optional. A page token, received from a previous calls.
   */
  pageToken?: string;
}

/**
 * Additional options for FirebaseCrashlytics#projectsAppsIssuesPatch.
 */
export interface ProjectsAppsIssuesPatchOptions {
  /**
   * Optional. The list of Issue fields to update. Currently only "state" is
   * mutable.
   */
  updateMask?: string /* FieldMask */;
}

function serializeProjectsAppsIssuesPatchOptions(data: any): ProjectsAppsIssuesPatchOptions {
  return {
    ...data,
    updateMask: data["updateMask"] !== undefined ? data["updateMask"] : undefined,
  };
}

function deserializeProjectsAppsIssuesPatchOptions(data: any): ProjectsAppsIssuesPatchOptions {
  return {
    ...data,
    updateMask: data["updateMask"] !== undefined ? data["updateMask"] : undefined,
  };
}

/**
 * Additional options for FirebaseCrashlytics#projectsAppsReportsGet.
 */
export interface ProjectsAppsReportsGetOptions {
  /**
   * Optional. Only count events from the given browser. This string matches
   * Browser.display_name. Format: "name (display_version)" e.g. "Chrome (123)",
   * or just "name" for all possible versions, e.g. simply "Chrome".
   */
  ["filter.browser.displayNames"]?: string;
  /**
   * Only counts events from the given Device model. This string matches
   * Device.display_name. Format: "manufacturer (model)" e.g. "Google (Pixel
   * 6)", or just "manufacturer" for all possible models, e.g. simply "Google".
   * Note that a device's marketing_name field can not be used for filtering.
   */
  ["filter.device.displayNames"]?: string;
  /**
   * Only counts events from devices with the given form factor (e.g. phone or
   * tablet).
   */
  ["filter.device.formFactors"]?:  | "FORM_FACTOR_UNSPECIFIED" | "PHONE" | "TABLET" | "DESKTOP" | "TV" | "WATCH";
  /**
   * Optional. Exclusive end of the interval. If specified, a Timestamp
   * matching this interval will have to be before the end.
   */
  ["filter.interval.endTime"]?: Date;
  /**
   * Optional. Inclusive start of the interval. If specified, a Timestamp
   * matching this interval will have to be the same or after the start.
   */
  ["filter.interval.startTime"]?: Date;
  /**
   * Optional. A space separated list of filter terms matched against the
   * contents of the issue. Contents include the title and the stack trace.
   * Matches must begin at alphanumeric tokens, i.e., 'util.Sorted' matches
   * 'java.util.SortedSet' but not 'myutil.SortedArray'. The filter matches if
   * all filter terms match. All non-alphanumeric characters are ignored for
   * matching. Filtering is assumed to be prefix-search and order-independent
   * unless phrases are surrounded by "". Any terms contained in quotes are
   * searched using exact-match (given filter term "foo", we will not return
   * "foobar"), and must appear in the order given exactly. To get
   * order-dependence but prefix-search, use a * within the quotes ("abc foo*"
   * will match "abc foobar", but not "foo abc" "abcd foobar", or "abc xyz
   * foobar").
   */
  ["filter.issue.content"]?: string;
  /**
   * Optional. Only counts events of the given error types. This field matches
   * [Issue.error_type].
   */
  ["filter.issue.errorTypes"]?:  | "ERROR_TYPE_UNSPECIFIED" | "FATAL" | "NON_FATAL" | "ANR";
  /**
   * Optional. Only counts events in the given issue ID. This field matches
   * [Issue.id].
   */
  ["filter.issue.id"]?: string;
  /**
   * Optional. Only returns issues currently marked with the given signals.
   * This field matches [Issue.signals.signal].
   */
  ["filter.issue.signals"]?:  | "SIGNAL_UNSPECIFIED" | "SIGNAL_EARLY" | "SIGNAL_FRESH" | "SIGNAL_REGRESSED" | "SIGNAL_REPETITIVE";
  /**
   * Optional. Deprecated: Prefer `states` field. Only includes events for
   * issues with the given issue state. Only available for `topIssues` reports.
   */
  ["filter.issue.state"]?:  | "STATE_UNSPECIFIED" | "OPEN" | "CLOSED" | "MUTED";
  /**
   * Optional. Only includes events for issues with the given issue states.
   * Only available for `topIssues` reports.
   */
  ["filter.issue.states"]?:  | "STATE_UNSPECIFIED" | "OPEN" | "CLOSED" | "MUTED";
  /**
   * Optional. Only counts events for the given issue variant ID. This field
   * matches [IssueVariant.id].
   */
  ["filter.issue.variantId"]?: string;
  /**
   * Only counts events in the given operating system and version. This string
   * matches OperatingSystem.display_name. Format: "osName (osVersion)" e.g.
   * "Android (11)". or just "osName" for all versions, e.g. simply "iPadOS".
   */
  ["filter.operatingSystem.displayNames"]?: string;
  /**
   * Only counts events in the given app version. This string matches
   * Version.display_name. Format: "display_version (build_version)" e.g. "1.2.3
   * (456)".
   */
  ["filter.version.displayNames"]?: string;
  /**
   * Optional. The report response will contain one data point per time grain.
   * If omitted, the report will contain a single data point for the complete
   * interval.
   */
  granularity?:  | "TIME_GRANULARITY_UNSPECIFIED" | "TIME_GRANULARITY_NONE" | "TIME_GRANULARITY_HOUR" | "TIME_GRANULARITY_DAY";
  /**
   * Optional. The maximum number of result groups to return. If omitted,
   * defaults to 25.
   */
  pageSize?: number;
  /**
   * Optional. A page token, received from a previous call. The page token is
   * only valid for the exact same set of filters, which must also be sent in
   * subsequent requests. This token is valid for 10 minutes after the first
   * request.
   */
  pageToken?: string;
}

function serializeProjectsAppsReportsGetOptions(data: any): ProjectsAppsReportsGetOptions {
  return {
    ...data,
    ["filter.interval.endTime"]: data["filter.interval.endTime"] !== undefined ? data["filter.interval.endTime"].toISOString() : undefined,
    ["filter.interval.startTime"]: data["filter.interval.startTime"] !== undefined ? data["filter.interval.startTime"].toISOString() : undefined,
  };
}

function deserializeProjectsAppsReportsGetOptions(data: any): ProjectsAppsReportsGetOptions {
  return {
    ...data,
    ["filter.interval.endTime"]: data["filter.interval.endTime"] !== undefined ? new Date(data["filter.interval.endTime"]) : undefined,
    ["filter.interval.startTime"]: data["filter.interval.startTime"] !== undefined ? new Date(data["filter.interval.startTime"]) : undefined,
  };
}

/**
 * Response message for the GetReport method. A report consists of the results
 * of a query over an application's events. The events may be filtered by
 * various criteria defined in the filters proto. The result will consist of a
 * number of paginated groups, of a type relevant to the report such as issues
 * or device models.
 */
export interface Report {
  /**
   * Output only. The displayable title of the report.
   */
  readonly displayName?: string;
  /**
   * Aggregate event statistics in the report will be grouped by a dimension,
   * such as by issue or by version. The response contains one element per
   * group, and all ReportGroup messages will have the same parent field.
   */
  groups?: ReportGroup[];
  /**
   * The name of the report. Format:
   * "projects/{project}/apps/{app_id}/reports/{report}".
   */
  name?: string;
  /**
   * Output only. A page token used to retrieve additional report groups. If
   * this field is not present, there are no subsequent pages available to
   * retrieve.
   */
  readonly nextPageToken?: string;
  /**
   * Output only. The total number of groups retrievable by the request.
   */
  readonly totalSize?: number;
  /**
   * Usage instructions for the report with a description of the result
   * metrics. This field contains a description of the underlying query and
   * describes the expected response data with any known caveats. This string
   * can be displayed in the UI of any integration that offers comprehensive
   * access to all Crashlytics reports.
   */
  usage?: string;
}

function serializeReport(data: any): Report {
  return {
    ...data,
    groups: data["groups"] !== undefined ? data["groups"].map((item: any) => (serializeReportGroup(item))) : undefined,
  };
}

function deserializeReport(data: any): Report {
  return {
    ...data,
    groups: data["groups"] !== undefined ? data["groups"].map((item: any) => (deserializeReportGroup(item))) : undefined,
  };
}

/**
 * A group of results in an EventReport. In any report, the group_parent field
 * is strictly the same type for all of the groups in any collection.
 */
export interface ReportGroup {
  /**
   * Browser metrics group.
   */
  browser?: Browser;
  /**
   * Device metrics group.
   */
  device?: Device;
  /**
   * Issue metrics group.
   */
  issue?: Issue;
  /**
   * Scalar metrics will contain a single object covering the entire interval,
   * while time-dimensioned graphs will contain one per time grain.
   */
  metrics?: IntervalMetrics[];
  /**
   * Operating system metrics group.
   */
  operatingSystem?: OperatingSystem;
  /**
   * When applicable, this field contains additional nested groupings. For
   * example, events can be grouped by operating system and by operating system
   * version.
   */
  subgroups?: ReportGroup[];
  /**
   * Issue variant metrics group.
   */
  variant?: IssueVariant;
  /**
   * Version metrics group.
   */
  version?: Version;
  /**
   * Web metrics group.
   */
  webMetricsGroup?: WebMetricsGroup;
}

function serializeReportGroup(data: any): ReportGroup {
  return {
    ...data,
    metrics: data["metrics"] !== undefined ? data["metrics"].map((item: any) => (serializeIntervalMetrics(item))) : undefined,
    subgroups: data["subgroups"] !== undefined ? data["subgroups"].map((item: any) => (serializeReportGroup(item))) : undefined,
  };
}

function deserializeReportGroup(data: any): ReportGroup {
  return {
    ...data,
    metrics: data["metrics"] !== undefined ? data["metrics"].map((item: any) => (deserializeIntervalMetrics(item))) : undefined,
    subgroups: data["subgroups"] !== undefined ? data["subgroups"].map((item: any) => (deserializeReportGroup(item))) : undefined,
  };
}

/**
 * Mobile device disk/flash usage. Not reported for all devices.
 */
export interface Storage {
  /**
   * Bytes free.
   */
  free?: bigint;
  /**
   * Bytes used.
   */
  used?: bigint;
}

function serializeStorage(data: any): Storage {
  return {
    ...data,
    free: data["free"] !== undefined ? String(data["free"]) : undefined,
    used: data["used"] !== undefined ? String(data["used"]) : undefined,
  };
}

function deserializeStorage(data: any): Storage {
  return {
    ...data,
    free: data["free"] !== undefined ? BigInt(data["free"]) : undefined,
    used: data["used"] !== undefined ? BigInt(data["used"]) : undefined,
  };
}

/**
 * An application thread.
 */
export interface Thread {
  /**
   * True when the Crashlytics analysis has determined that the stacktrace in
   * this thread is where the fault occurred.
   */
  blamed?: boolean;
  /**
   * The address of the signal that caused the application to crash. Only
   * present on crashed native threads.
   */
  crashAddress?: bigint;
  /**
   * True when the thread has crashed.
   */
  crashed?: boolean;
  /**
   * The frames in the thread's stacktrace.
   */
  frames?: Frame[];
  /**
   * The name of the thread.
   */
  name?: string;
  /**
   * The queue on which the thread was running.
   */
  queue?: string;
  /**
   * The name of the signal that caused the app to crash. Only present on
   * crashed native threads.
   */
  signal?: string;
  /**
   * The code of the signal that caused the app to crash. Only present on
   * crashed native threads.
   */
  signalCode?: string;
  /**
   * The subtitle of the thread.
   */
  subtitle?: string;
  /**
   * The system id of the thread, only available for ANR threads.
   */
  sysThreadId?: bigint;
  /**
   * The id of the thread, only available for ANR threads.
   */
  threadId?: bigint;
  /**
   * Output only. The state of the thread at the time the ANR occurred.
   */
  readonly threadState?:  | "STATE_UNSPECIFIED" | "THREAD_STATE_TERMINATED" | "THREAD_STATE_RUNNABLE" | "THREAD_STATE_TIMED_WAITING" | "THREAD_STATE_BLOCKED" | "THREAD_STATE_WAITING" | "THREAD_STATE_NEW" | "THREAD_STATE_NATIVE_RUNNABLE" | "THREAD_STATE_NATIVE_WAITING";
  /**
   * The title of the thread.
   */
  title?: string;
}

function serializeThread(data: any): Thread {
  return {
    ...data,
    crashAddress: data["crashAddress"] !== undefined ? String(data["crashAddress"]) : undefined,
    frames: data["frames"] !== undefined ? data["frames"].map((item: any) => (serializeFrame(item))) : undefined,
    sysThreadId: data["sysThreadId"] !== undefined ? String(data["sysThreadId"]) : undefined,
    threadId: data["threadId"] !== undefined ? String(data["threadId"]) : undefined,
  };
}

function deserializeThread(data: any): Thread {
  return {
    ...data,
    crashAddress: data["crashAddress"] !== undefined ? BigInt(data["crashAddress"]) : undefined,
    frames: data["frames"] !== undefined ? data["frames"].map((item: any) => (deserializeFrame(item))) : undefined,
    sysThreadId: data["sysThreadId"] !== undefined ? BigInt(data["sysThreadId"]) : undefined,
    threadId: data["threadId"] !== undefined ? BigInt(data["threadId"]) : undefined,
  };
}

/**
 * Request message for the UpdateIssue method.
 */
export interface UpdateIssueRequest {
  /**
   * Required. The issue to update. The issue's `name` field is used to
   * identify the issue to update. Format:
   * "projects/{project}/apps/{app}/issues/{issue}".
   */
  issue?: Issue;
  /**
   * Optional. The list of Issue fields to update. Currently only "state" is
   * mutable.
   */
  updateMask?: string /* FieldMask */;
}

function serializeUpdateIssueRequest(data: any): UpdateIssueRequest {
  return {
    ...data,
    updateMask: data["updateMask"] !== undefined ? data["updateMask"] : undefined,
  };
}

function deserializeUpdateIssueRequest(data: any): UpdateIssueRequest {
  return {
    ...data,
    updateMask: data["updateMask"] !== undefined ? data["updateMask"] : undefined,
  };
}

/**
 * Developer-provided end user identifiers.
 */
export interface User {
  /**
   * User id if provided by the app developer.
   */
  id?: string;
}

/**
 * Application software version.
 */
export interface Version {
  /**
   * Mobile only. One display_version can have many build_version. On Android,
   * strictly the same as "version code". On iOS, strictly the same as "build
   * number" or CFBundleVersion.
   */
  buildVersion?: string;
  /**
   * Compound readable string containing both display and build versions.
   * Format: "display_version (build_version)" e.g. "1.2.3 (456)". This string
   * can be used for filtering with the VersionFilter.display_name field.
   */
  displayName?: string;
  /**
   * Readable version string, e.g. "1.2.3". On Android, strictly the same as
   * "version name". On iOS, strictly the same as "version number" or
   * CFBundleShortVersionString.
   */
  displayVersion?: string;
  /**
   * Indicates releases which have artifacts that are currently available in
   * the Play Store to the target audience of the track. Versions may be
   * available in multiple tracks.
   */
  tracks?: PlayTrack[];
}

/**
 * Represents a grouping for metrics specific to web applications.
 */
export interface WebMetricsGroup {
  /**
   * The id of the web metrics group
   */
  id?: string;
}