syntax = "proto3";

import "annotations.proto";
import "common.proto";
import "enum.proto";

option java_package = "com.afreecatv.mobile.sdk.proto";
option java_outer_classname = "ColonyProto";

service Colony {
  rpc Stream(stream StreamRequest) returns (stream StreamResponse) {
    // option (google.api.http) = {post: "/stream", body: "*"};
    option (google.api.http) = {get: "/stream"};
  }
}

message StreamRequest {
  oneof packet {
    // 001 ~ 600 (etc)
    KeepAlive keepAlive = 1;
    InitEntry initEntry = 2;
    ChangeInfo changeInfo = 3;

    // 601 ~ 900 (P2P 관련)
    PeerAllocNode peerAllocNode = 601;
    PeerRemoveNode peerRemoveNode = 602;
    PeerSignaling peerSignaling = 603;
    PeerCompleted peerCompleted = 604;

    UploadStart uploadStart = 701;
    UploadData uploadData = 702;
    UploadEnd uploadEnd = 703;
  }

  message KeepAlive {
  }

  message InitEntry {
    string uuid = 1;
    string userId = 2; // 로그인한 유저의 경우 id 기입
    ClientType clientType = 3;
    NetworkType networkType = 4;
    string content = 5; // API에서 암호화한 데이터
    map<string, LogValue> nodeLog = 100; // node log(로그 추적용)
  }

  // 시청 중간에 로그인/로그아웃 발생 시 변경된 값(userId) 적용을 위해
  message ChangeInfo {
    string userId = 1; // 로그인한 유저의 경우 id 기입
  }

  // 노드 할당 요청
  message PeerAllocNode {
    string streamType = 1; // sd, hd 등의 화질 정보
    string prevPeerSessionId = 2; // 이전 피어가 있으면
  }

  // 노드 제거 요청
  message PeerRemoveNode {
    string streamType = 1; // sd, hd 등의 화질 정보
    int32 reason = 2; // 0 : 일반 종료(세션 끊어짐 포함), 1 : 부모 변경(클라이언트 상황별 상세한 사유를 위해 더 늘려도 됨), 999 : 서버가 유저 세션 끊김 감지하여 처리한 경우, etc...
  }

  // WebRTC 데이터 교환 패킷
  message PeerSignaling {
    string peerSessionId = 1; // 클라이언트가 관리할 수 있도록 연결될 상대방의 sessionId정보를 전달한다.
    bytes data = 2; // 시그널링 데이터 SDP Or ICECandidate Data
  }

  // 부모 자식간 연결이 완료되면 보내줘야하는 패킷(양측 누가 보내도 무관)
  message PeerCompleted {
    string childSessionId = 1; // 자식의 세션 아이디
    string streamType = 2; // sd, hd 등의 화질 정보
    string parentSessionId = 3; // 부모의 세션 아이디
  }

  // 속도체크
  message UploadStart {
  }

  message UploadData {
    bytes checkData = 1;
  }

  message UploadEnd {
  }
  // 속도체크 끝

  // 공통 10001 ~
  uint32 broadNo = 10001;
  uint32 sequence = 10002; // event driven 방식에서 여러 객체가 한통로를 사용할 때 구분하기 위함
  int64 timestamp = 10003; // 속도 체크용 타임 스탬프
}

message StreamResponse {
  oneof packet {
    // 001 ~ 600 (etc)
    KeepAlive keepAlive = 1;
    InitEntry initEntry = 2;
    // ChangeInfo changeInfo = 3; => 사용금지

    // 601 ~ 900 (P2P 관련)
    PeerAllocNode peerAllocNode = 601;
    // PeerRemoveNode peerRemoveNode = 602; => 사용금지
    PeerSignaling peerSignaling = 603;
    // PeerCompleted peerCompleted = 604; => 사용금지

    UploadStart uploadStart = 701;
    // UploadData uploadData = 702; => 사용금지
    UploadEnd uploadEnd = 703;
  }

  message KeepAlive {
    int64 serverTime = 1; // 서버 타임 전달
  }

  message InitEntry {
    int64 serverTime = 1; // 서버 타임 전달
    string sessionId = 2; // 본인의 세션아이디 전달
  }

  // 노드 할당 응답
  message PeerAllocNode {
    string streamType = 1; // sd, hd 등의 화질 정보
    bool isRoot = 2;
    bool isOffer = 3; // 본인이 Offer(부모)의 역할을 해야하는지 판단한다.
    string peerSessionId = 4; // 상대방의 세션 ID, SDP, ICECandidate 전달 할 때 돌려받아야하는 패킷
  }

  // WebRTC 데이터 교환 패킷
  message PeerSignaling {
    string peerSessionId = 1; // 클라이언트가 관리할 수 있도록 연결될 상대방의 sessionId정보를 전달한다.
    bytes data = 2; // 시그널링 데이터 SDP Or ICECandidate Data => 후하니 요청으로 bytes로 변경
  }

  // 속도체크
  message UploadStart {
    uint32 splitBytes = 1;
    uint32 checkCount = 2;
  }

  message UploadEnd {
    uint32 uploadKbps = 1;
  }
  // 속도체크 끝

  // 특수 코드
  int32 result = 10000; // 처리 결과

  // 공통 10001 ~
  uint32 broadNo = 10001;
  uint32 sequence = 10002;
  int64 timestamp = 10003; // 속도 체크용 타임 스탬프
}

