syntax = "proto3";

// gRPC for our DBaaS central service
//
// notably uses gRPC-Gateway with OpenAPI
package billing;

import "google/protobuf/empty.proto";
import "google/api/annotations.proto";
import "protoc-gen-openapiv2/options/annotations.proto";

option go_package = "pkg/service/billing/;billing";

service BillingService {
    rpc SetupIntent (OrgIdReq) returns (SetupIntentResp) {
        option (google.api.http) = {
            post: "/api/v1/orgs/{org_id}/billing/setup-intent"
            body: "*"
        };
    }

    rpc ListPaymentMethods (StripePaginationParam) returns (PaymentMethods) {
        option (google.api.http) = {
            get: "/api/v1/orgs/{org_id}/billing/payment-methods"
        };
    }
    rpc DeletePaymentMethod (OrgAndPaymentID) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            delete: "/api/v1/orgs/{org_id}/billing/payment-methods/{payment_method_id}"
        };
    }
    rpc UpdatePaymentMethod (PaymentMethod) returns (PaymentMethod) {
        option (google.api.http) = {
            put: "/api/v1/orgs/{org_id}/billing/payment-methods/{id}"
            body: "*"
        };
    }
    rpc ListInvoices (StripePaginationParam) returns (Invoices) {
        option (google.api.http) = {
            get: "/api/v1/orgs/{org_id}/billing/invoices"
        };
    }
    rpc ListCredits (OrgIdReq) returns (Credits) {
        option (google.api.http) = {
            get: "/api/v1/orgs/{org_id}/billing/credits"
        };
    }
    rpc GetCustomerBillingInfo (OrgIdReq) returns (BillingInfo) {
        option (google.api.http) = {
            get: "/api/v1/orgs/{org_id}/billing/info"
        };
    }
    rpc UpdateCustomerBillingInfo (BillingInfo) returns (BillingInfo) {
        option (google.api.http) = {
            put: "/api/v1/orgs/{org_id}/billing/info"
            body:"*"
        };
    }
    rpc GetCurrentBillingCycle (OrgIdReq) returns (CurrentBillingCycle) {
        option (google.api.http) = {
            get: "/api/v1/orgs/{org_id}/billing/current-billing-cycle"
        };
    }
    rpc GetMonthUsageGroupByProject (MonthUsageGroupByProjectReq) returns (MonthUsageGroupByProjectResp) {
        option (google.api.http) = {
            get: "/api/v1/orgs/{org_id}/billing/month-usage-group-by-project"
        };
    }
}


message OrgIdReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["org_id"]
        }
    };

    uint64 org_id = 1;
}


message ProjectIdReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["org_id", "project_id"]
        }
    };

    uint64 org_id = 1;
    uint64 project_id = 2;
}

message SetupIntentResp {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["public_key", "client_secret"]
        }
    };

    string public_key = 1;
    string client_secret = 2;
}


message StripePaginationParam {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["limit", "starting_after", "ending_before", "org_id"]
        }
    };

    int32 limit = 1;
    string starting_after = 2;
    string ending_before = 3;
    uint64 org_id = 4;
}


message OrgAndPaymentID {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["org_id", "payment_method_id"]
        }
    };

    uint64 org_id = 1;
    string payment_method_id = 2;
}

message PaymentMethod {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["id", "billing_details", "org_id"]
        }
    };

    string id = 1;
    CreditCard  card  = 2;
    BillingDetails billing_details = 3;
    uint64 org_id = 4;
}

message BillingDetails {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["address", "email", "name", "phone"]
        }
    };

    Address address = 1;
    string email = 2;
    string name = 3;
    string phone = 4;
}

message Address {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["city", "country", "line1", "line2", "postal_code", "state"]
        }
    };

    string city = 1;
    string country = 2;
    string line1 = 3;
    string line2 = 4;
    string postal_code = 5;
    string state = 6;
}


message PaymentMethods {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["has_more", "items"]
        }
    };

    bool has_more = 1;
    repeated PaymentMethod items = 2;
}

message CreditCard  {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["brand", "country", "exp_month", "exp_year", "fingerprint", "funding", "last4"]
        }
    };

    string brand = 1;
    string country = 2;
    uint64 exp_month =3;
    uint64 exp_year = 4;
    string fingerprint = 5;
    string funding = 6;
    string last4 = 7;
}

message Invoices {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["has_more", "items"]
        }
    };

    bool has_more = 1;
    repeated Invoice items = 2;
}

message Invoice {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["id", "amount_due", "amount_paid", "created", "currency", "due_date", "credit_used", "number", "invoice_pdf", "total", "paid", "status"]
        }
    };

    string id = 1;
    int64 amount_due = 2;
    int64 amount_paid = 3;
    int64 created = 4;
    string currency = 5;
    int64 due_date = 6;
    int64 credit_used = 7;
    string number = 8;
    string invoice_pdf = 9;
    int64 total = 10;
    bool paid = 11;
    string status = 12;
}

message Credits {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["total", "items"]
        }
    };

    int32 total = 1;
    repeated Credit items = 2;
}

message Credit {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["id", "amount", "created"]
        }
    };

    uint64 id = 1;
    int64 amount = 2;
    int64 created = 3;
}

message BillingInfo {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["id", "dbaas_id", "email", "name", "description", "default_source", "org_id", "address", "billing_email"]
        }
    };

    string id = 1;
    string dbaas_id = 2;
    string email = 3;
    string name = 4;
    string description = 5;
    string default_source = 6;
    uint64 org_id = 7;
    Address address = 8;
    string billing_email = 9;
}

message CurrentBillingCycle {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["time", "current_usage", "currency", "has_draft_invoice"]
        }
    };

    int64 time = 1;
    int64 current_usage =2;
    string currency = 3;
    bool has_draft_invoice = 4;
}

message MonthUsageGroupByProjectReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["year", "month", "org_id"]
        }
    };
    int32 year = 1;
    int32 month = 2;
    uint64 org_id = 3;
}

message MonthUsageGroupByProjectResp {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["projects", "total_usage"]
        }
    };
    repeated ProjectUsage projects =1;
    int64 total_usage = 2;
}

message ProjectUsage {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["project_id", "project_name", "usage"]
        }
    };
    uint64 project_id = 1;
    string project_name = 2;
    int64 usage = 3;
}
