schema {
  query: Query
  mutation: Mutation
}

enum AuthMethod {
  NONE
  PLAIN
  LOGIN
}

enum Encryption {
  START_TLS
  SSL_TLS
  NONE
}

enum EventKind {
  COMPLETION
  SELECT
  VIEW
  DISMISS
}

enum IntegrationKind {
  GITHUB
  GITLAB
  GITHUB_SELF_HOSTED
  GITLAB_SELF_HOSTED
}

enum IntegrationStatus {
  READY
  PENDING
  FAILED
}

enum Language {
  RUST
  PYTHON
  JAVA
  KOTLIN
  JAVASCRIPT
  TYPESCRIPT
  GO
  RUBY
  CSHARP
  C
  CPP
  SOLIDITY
  OTHER
}

enum LicenseStatus {
  OK
  EXPIRED
  SEATS_EXCEEDED
}

enum LicenseType {
  COMMUNITY
  TEAM
  ENTERPRISE
}

enum OAuthProvider {
  GITHUB
  GOOGLE
  GITLAB
}

enum RepositoryKind {
  GIT
  GITHUB
  GITLAB
  GITHUB_SELF_HOSTED
  GITLAB_SELF_HOSTED
}

input CreateIntegrationInput {
  displayName: String!
  accessToken: String!
  kind: IntegrationKind!
  apiBase: String
}

input CreateWebCrawlerUrlInput {
  url: String!
}

input EmailSettingInput {
  smtpUsername: String!
  fromAddress: String!
  smtpServer: String!
  smtpPort: Int!
  encryption: Encryption!
  authMethod: AuthMethod!
  smtpPassword: String
}

input NetworkSettingInput {
  externalUrl: String!
}

input PasswordChangeInput {
  oldPassword: String
  newPassword1: String!
  newPassword2: String!
}

input PasswordResetInput {
  code: String!
  password1: String!
  password2: String!
}

input RequestInvitationInput {
  email: String!
}

input RequestPasswordResetEmailInput {
  email: String!
}

input SecuritySettingInput {
  allowedRegisterDomainList: [String!]!
  disableClientSideTelemetry: Boolean!
}

input UpdateIntegrationInput {
  id: ID!
  displayName: String!
  accessToken: String
  apiBase: String
  kind: IntegrationKind!
}

input UpdateOAuthCredentialInput {
  provider: OAuthProvider!
  clientId: String!
  clientSecret: String
}

"""
  Combined date and time (with time zone) in [RFC 3339][0] format.

  Represents a description of an exact instant on the time-line (such as the
  instant that a user account was created).

  [`DateTime` scalar][1] compliant.

  See also [`chrono::DateTime`][2] for details.

  [0]: https://datatracker.ietf.org/doc/html/rfc3339#section-5
  [1]: https://graphql-scalars.dev/docs/scalars/date-time
  [2]: https://docs.rs/chrono/latest/chrono/struct.DateTime.html
"""
scalar DateTime

type CompletionStats {
  start: DateTime!
  end: DateTime!
  language: Language!
  completions: Int!
  views: Int!
  selects: Int!
}

type DiskUsage {
  filepath: [String!]!
  "Size in kilobytes."
  sizeKb: Float!
}

type DiskUsageStats {
  events: DiskUsage!
  indexedRepositories: DiskUsage!
  database: DiskUsage!
  models: DiskUsage!
}

type EmailSetting {
  smtpUsername: String!
  smtpServer: String!
  smtpPort: Int!
  fromAddress: String!
  encryption: Encryption!
  authMethod: AuthMethod!
}

type FileEntrySearchResult {
  type: String!
  path: String!
  "matched indices for fuzzy search query."
  indices: [Int!]!
}

type GitRepository {
  id: ID!
  name: String!
  gitUrl: String!
  refs: [String!]!
  jobInfo: JobInfo!
}

type GrepFile {
  path: String!
  lines: [GrepLine!]!
}

type GrepLine {
  "Content of the line."
  line: GrepTextOrBase64!
  "Byte offset in the file to the start of the line."
  byteOffset: Int!
  "Line number in the file, starting from 1."
  lineNumber: Int!
  "The matches in the line."
  subMatches: [GrepSubMatch!]!
}

type GrepSubMatch {
  bytesStart: Int!
  bytesEnd: Int!
}

type GrepTextOrBase64 {
  text: String
  base64: String
}

type Integration {
  id: ID!
  kind: IntegrationKind!
  displayName: String!
  accessToken: String!
  apiBase: String
  createdAt: DateTime!
  updatedAt: DateTime!
  status: IntegrationStatus!
}

type IntegrationConnection {
  edges: [IntegrationEdge!]!
  pageInfo: PageInfo!
}

type IntegrationEdge {
  node: Integration!
  cursor: String!
}

type Invitation {
  id: ID!
  email: String!
  code: String!
  createdAt: DateTime!
}

type InvitationConnection {
  edges: [InvitationEdge!]!
  pageInfo: PageInfo!
}

type InvitationEdge {
  node: Invitation!
  cursor: String!
}

type JobInfo {
  "Last run of the job."
  lastJobRun: JobRun
  "The command to submit job run using triggerJobRun mutation."
  command: String!
}

type JobRun {
  id: ID!
  job: String!
  createdAt: DateTime!
  updatedAt: DateTime!
  startedAt: DateTime
  finishedAt: DateTime
  exitCode: Int
  stdout: String!
  stderr: String!
}

type JobRunConnection {
  edges: [JobRunEdge!]!
  pageInfo: PageInfo!
}

type JobRunEdge {
  node: JobRun!
  cursor: String!
}

type JobStats {
  success: Int!
  failed: Int!
  pending: Int!
}

type LicenseInfo {
  type: LicenseType!
  status: LicenseStatus!
  seats: Int!
  seatsUsed: Int!
  issuedAt: DateTime
  expiresAt: DateTime
}

type Mutation {
  resetRegistrationToken: String!
  requestInvitationEmail(input: RequestInvitationInput!): Invitation!
  requestPasswordResetEmail(input: RequestPasswordResetEmailInput!): Boolean!
  passwordReset(input: PasswordResetInput!): Boolean!
  passwordChange(input: PasswordChangeInput!): Boolean!
  resetUserAuthToken: Boolean!
  logoutAllSessions: Boolean!
  updateUserActive(id: ID!, active: Boolean!): Boolean!
  updateUserRole(id: ID!, isAdmin: Boolean!): Boolean!
  uploadUserAvatarBase64(id: ID!, avatarBase64: String): Boolean!
  updateUserName(id: ID!, name: String!): Boolean!
  register(email: String!, password1: String!, password2: String!, invitationCode: String, name: String!): RegisterResponse!
  tokenAuth(email: String!, password: String!): TokenAuthResponse!
  verifyToken(token: String!): Boolean!
  refreshToken(refreshToken: String!): RefreshTokenResponse!
  createInvitation(email: String!): ID!
  sendTestEmail(to: String!): Boolean!
  createGitRepository(name: String!, gitUrl: String!): ID!
  deleteGitRepository(id: ID!): Boolean!
  updateGitRepository(id: ID!, name: String!, gitUrl: String!): Boolean!
  deleteInvitation(id: ID!): ID!
  updateOauthCredential(input: UpdateOAuthCredentialInput!): Boolean!
  deleteOauthCredential(provider: OAuthProvider!): Boolean!
  updateEmailSetting(input: EmailSettingInput!): Boolean!
  updateSecuritySetting(input: SecuritySettingInput!): Boolean!
  updateNetworkSetting(input: NetworkSettingInput!): Boolean!
  deleteEmailSetting: Boolean!
  uploadLicense(license: String!): Boolean!
  resetLicense: Boolean!
  createIntegration(input: CreateIntegrationInput!): ID!
  updateIntegration(input: UpdateIntegrationInput!): Boolean!
  deleteIntegration(id: ID!, kind: IntegrationKind!): Boolean!
  updateIntegratedRepositoryActive(id: ID!, active: Boolean!): Boolean!
  "Trigger a job run given its param string."
  triggerJobRun(command: String!): ID!
  createWebCrawlerUrl(input: CreateWebCrawlerUrlInput!): ID!
  deleteWebCrawlerUrl(id: ID!): Boolean!
}

type NetworkSetting {
  externalUrl: String!
}

type OAuthCredential {
  provider: OAuthProvider!
  clientId: String!
  createdAt: DateTime!
  updatedAt: DateTime!
}

type PageInfo {
  hasPreviousPage: Boolean!
  hasNextPage: Boolean!
  startCursor: String
  endCursor: String
}

type ProvidedRepository {
  id: ID!
  integrationId: ID!
  active: Boolean!
  displayName: String!
  gitUrl: String!
  vendorId: String!
  createdAt: DateTime!
  updatedAt: DateTime!
  refs: [String!]!
  jobInfo: JobInfo!
}

type ProvidedRepositoryConnection {
  edges: [ProvidedRepositoryEdge!]!
  pageInfo: PageInfo!
}

type ProvidedRepositoryEdge {
  node: ProvidedRepository!
  cursor: String!
}

type Query {
  registrationToken: String!
  me: User!
  users(after: String, before: String, first: Int, last: Int): UserConnection!
  invitations(after: String, before: String, first: Int, last: Int): InvitationConnection!
  jobRuns(ids: [ID!], jobs: [String!], after: String, before: String, first: Int, last: Int): JobRunConnection!
  jobRunStats(jobs: [String!]): JobStats!
  emailSetting: EmailSetting
  networkSetting: NetworkSetting!
  securitySetting: SecuritySetting!
  gitRepositories(after: String, before: String, first: Int, last: Int): RepositoryConnection!
  "Search files that matches the pattern in the repository."
  repositorySearch(kind: RepositoryKind!, id: ID!, rev: String, pattern: String!): [FileEntrySearchResult!]!
  """
    File content search with a grep-like experience.

    Syntax:

    1. Unprefixed text will be treated as a regex pattern for file content search.
    2. 'f:' to search by file name with a regex pattern.
    3. 'lang:' to search by file language.
    4. All tokens can be negated by prefixing them with '-'.

    Examples:
    * `f:schema -lang:rust fn`
    * `func_name lang:go`
  """
  repositoryGrep(kind: RepositoryKind!, id: ID!, rev: String, query: String!): [GrepFile!]!
  oauthCredential(provider: OAuthProvider!): OAuthCredential
  oauthCallbackUrl(provider: OAuthProvider!): String!
  serverInfo: ServerInfo!
  license: LicenseInfo!
  jobs: [String!]!
  dailyStatsInPastYear(users: [ID!]): [CompletionStats!]!
  dailyStats(start: DateTime!, end: DateTime!, users: [ID!], languages: [Language!]): [CompletionStats!]!
  userEvents(after: String, before: String, first: Int, last: Int, users: [ID!], start: DateTime!, end: DateTime!): UserEventConnection!
  diskUsageStats: DiskUsageStats!
  repositoryList: [Repository!]!
  integrations(ids: [ID!], kind: IntegrationKind, after: String, before: String, first: Int, last: Int): IntegrationConnection!
  integratedRepositories(ids: [ID!], kind: IntegrationKind, active: Boolean, after: String, before: String, first: Int, last: Int): ProvidedRepositoryConnection!
  webCrawlerUrls(after: String, before: String, first: Int, last: Int): WebCrawlerUrlConnection!
}

type RefreshTokenResponse {
  accessToken: String!
  refreshToken: String!
  refreshExpiresAt: DateTime!
}

type RegisterResponse {
  accessToken: String!
  refreshToken: String!
}

type Repository {
  id: ID!
  name: String!
  kind: RepositoryKind!
  gitUrl: String!
  refs: [String!]!
}

type RepositoryConnection {
  edges: [RepositoryEdge!]!
  pageInfo: PageInfo!
}

type RepositoryEdge {
  node: GitRepository!
  cursor: String!
}

type SecuritySetting {
  allowedRegisterDomainList: [String!]!
  disableClientSideTelemetry: Boolean!
}

type ServerInfo {
  isAdminInitialized: Boolean!
  isChatEnabled: Boolean!
  isEmailConfigured: Boolean!
  allowSelfSignup: Boolean!
  isDemoMode: Boolean!
}

type TokenAuthResponse {
  accessToken: String!
  refreshToken: String!
}

type User {
  id: ID!
  email: String!
  name: String!
  isAdmin: Boolean!
  isOwner: Boolean!
  authToken: String!
  createdAt: DateTime!
  active: Boolean!
  isPasswordSet: Boolean!
}

type UserConnection {
  edges: [UserEdge!]!
  pageInfo: PageInfo!
}

type UserEdge {
  node: User!
  cursor: String!
}

type UserEvent {
  id: ID!
  userId: ID!
  kind: EventKind!
  createdAt: DateTime!
  payload: String!
}

type UserEventConnection {
  edges: [UserEventEdge!]!
  pageInfo: PageInfo!
}

type UserEventEdge {
  node: UserEvent!
  cursor: String!
}

type WebCrawlerUrl {
  url: String!
  id: ID!
  createdAt: DateTime!
  jobInfo: JobInfo!
}

type WebCrawlerUrlConnection {
  edges: [WebCrawlerUrlEdge!]!
  pageInfo: PageInfo!
}

type WebCrawlerUrlEdge {
  node: WebCrawlerUrl!
  cursor: String!
}
