enum Role {
  Owner
  Maintainer
  Reader
}

enum Permission {
  View
  Edit
}

enum Environment {
  Production
  Preview
  Development
}

enum DeploymentStatus {
  Building
  Ready
  Error
  Deleting
}

enum AuctionStatus {
  completed
  reveal
  commit
  expired
}

enum DomainStatus {
  Live
  Pending
}

type User {
  id: String!
  name: String
  email: String!
  organizations: [Organization!]
  projects: [Project!]
  isVerified: Boolean!
  createdAt: String!
  updatedAt: String!
  gitHubToken: String
}

type Organization {
  id: String!
  name: String!
  slug: String!
  projects: [Project!]
  createdAt: String!
  updatedAt: String!
  members: [OrganizationMember!]
}

type OrganizationMember {
  id: String!
  member: User!
  role: Role!
  createdAt: String!
  updatedAt: String!
}

type Project {
  id: String!
  owner: User!
  deployments: [Deployment!]
  name: String!
  repository: String!
  prodBranch: String!
  description: String
  deployers: [Deployer!]
  auctionId: String
  fundsReleased: Boolean
  template: String
  framework: String
  paymentAddress: String!
  txHash: String!
  webhooks: [String!]
  members: [ProjectMember!]
  environmentVariables: [EnvironmentVariable!]
  createdAt: String!
  updatedAt: String!
  organization: Organization!
  icon: String
  baseDomains: [String!]
}

type ProjectMember {
  id: String!
  member: User!
  permissions: [Permission!]!
  isPending: Boolean!
  createdAt: String!
  updatedAt: String!
}

type Deployment {
  id: String!
  domain: Domain
  branch: String!
  commitHash: String!
  commitMessage: String!
  url: String
  environment: Environment!
  deployer: Deployer
  applicationDeploymentRequestId: String
  isCurrent: Boolean!
  baseDomain: String
  status: DeploymentStatus!
  createdAt: String!
  updatedAt: String!
  createdBy: User!
}

type Domain {
  id: String!
  branch: String!
  name: String!
  redirectTo: Domain
  status: DomainStatus!
  createdAt: String!
  updatedAt: String!
}

type EnvironmentVariable {
  id: String!
  environment: Environment!
  key: String!
  value: String!
  createdAt: String!
  updatedAt: String!
}

type Deployer {
  deployerLrn: String!
  deployerId: String!
  deployerApiUrl: String!
  minimumPayment: String
  paymentAddress: String
  createdAt: String!
  updatedAt: String!
  baseDomain: String
}

type AuthResult {
  token: String!
}

input AddEnvironmentVariableInput {
  environments: [Environment!]!
  key: String!
  value: String!
}

input AddProjectFromTemplateInput {
  templateOwner: String!
  templateRepo: String!
  owner: String!
  name: String!
  isPrivate: Boolean!
  paymentAddress: String!
  txHash: String!
}

input AddProjectInput {
  name: String!
  repository: String!
  prodBranch: String!
  template: String
  paymentAddress: String!
  txHash: String!
}

input UpdateProjectInput {
  name: String
  description: String
  prodBranch: String
  organizationId: String
  webhooks: [String!]
}

input AddDomainInput {
  name: String!
}

input UpdateDomainInput {
  name: String
  branch: String
  redirectToId: String
}

input UpdateEnvironmentVariableInput {
  key: String
  value: String
}

input AddProjectMemberInput {
  email: String!
  permissions: [Permission!]
}

input UpdateProjectMemberInput {
  permissions: [Permission]
}

input FilterDomainsInput {
  branch: String
  status: DomainStatus
}

type Fee {
  type: String!
  quantity: String!
}

type Bid {
  auctionId: String!
  bidderAddress: String!
  status: String!
  commitHash: String!
  commitTime: String
  commitFee: Fee
  revealTime: String
  revealFee: Fee
  bidAmount: Fee
}

type Auction {
  id: String!
  kind: String!
  status: String!
  ownerAddress: String!
  createTime: String!
  commitsEndTime: String!
  revealsEndTime: String!
  commitFee: Fee!
  revealFee: Fee!
  minimumBid: Fee
  winnerAddresses: [String!]!
  winnerBids: [Fee!]
  winnerPrice: Fee
  maxPrice: Fee
  numProviders: Int!
  fundsReleased: Boolean!
  bids: [Bid!]!
}

input AuctionParams {
  maxPrice: String,
  numProviders: Int,
}

type Query {
  user: User!
  organizations: [Organization!]
  projects: [Project!]
  projectsInOrganization(organizationSlug: String!): [Project!]
  project(projectId: String!): Project
  deployments(projectId: String!): [Deployment!]
  environmentVariables(projectId: String!): [EnvironmentVariable!]
  projectMembers(projectId: String!): [ProjectMember!]
  searchProjects(searchText: String!): [Project!]
  getAuctionData(auctionId: String!): Auction!
  domains(projectId: String!, filter: FilterDomainsInput): [Domain]
  deployers: [Deployer]
  address: String!
  verifyTx(txHash: String!, amount: String!, senderAddress: String!): Boolean!
}

type Mutation {
  addProjectMember(projectId: String!, data: AddProjectMemberInput): Boolean!
  updateProjectMember(
    projectMemberId: String!
    data: UpdateProjectMemberInput
  ): Boolean!
  removeProjectMember(projectMemberId: String!): Boolean!
  addEnvironmentVariables(
    projectId: String!
    data: [AddEnvironmentVariableInput!]
  ): Boolean!
  updateEnvironmentVariable(
    environmentVariableId: String!
    data: UpdateEnvironmentVariableInput!
  ): Boolean!
  removeEnvironmentVariable(environmentVariableId: String!): Boolean!
  updateDeploymentToProd(deploymentId: String!): Boolean!
  addProjectFromTemplate(
    organizationSlug: String!
    data: AddProjectFromTemplateInput
    lrn: String
    auctionParams: AuctionParams
    environmentVariables: [AddEnvironmentVariableInput!]
  ): Project!
  addProject(
    organizationSlug: String!
    data: AddProjectInput!
    lrn: String
    auctionParams: AuctionParams
    environmentVariables: [AddEnvironmentVariableInput!]
  ): Project!
  updateProject(projectId: String!, data: UpdateProjectInput): Boolean!
  redeployToProd(deploymentId: String!): Boolean!
  deleteProject(projectId: String!): Boolean!
  deleteDomain(domainId: String!): Boolean!
  rollbackDeployment(projectId: String!, deploymentId: String!): Boolean!
  deleteDeployment(deploymentId: String!): Boolean!
  addDomain(projectId: String!, data: AddDomainInput!): Boolean!
  updateDomain(domainId: String!, data: UpdateDomainInput!): Boolean!
  authenticateGitHub(code: String!): AuthResult!
  unauthenticateGitHub: Boolean!
}
