// Protocol Buffer for TeraChem server mode

syntax = "proto3"; // Want Proto3 for C# interface to visualizer
// Slight hiccup because I need .Net 4.5 for protobuf and Unity uses 3.5

package terachem_server;

option csharp_namespace = "Google.Protobuf.TeraChem";

// In TeraChem, I will require a header before getting a protocol buffer
// Header will be 8 bytes (2 int32's)
// First 4 bytes will tell me what message I received, as denoted by the following enum
// Second 4 bytes will be byte size of protobuf (not including header)
enum MessageType {
  STATUS = 0;
  MOL = 1;
  JOBINPUT = 2;
  JOBOUTPUT = 3;
}

// Status message from server to client
message Status {
  bool busy = 1;

  // One of these will be set:
  // On successful job acceptance by server, send an accepted message. On decline, they will just get back busy and no job status
  // If client requests status during job, send a working message
  // If client requests status after job, send a completed message and then job output
  oneof job_status {
    bool accepted = 2;
    bool working = 3;
    bool completed = 4;
  }

  // Server job information
  string job_dir = 5;
  string job_scr_dir = 6;
  int32 server_job_id = 7;
}

// Molecule message
message Mol {
  // Atom types
  repeated string atoms = 1;

  // Coordinates
  repeated double xyz = 2;
  
  // Unit type, matching current params.cpp definition
  enum UnitType {
    ANGSTROM = 0;
    BOHR = 1;
  }
  UnitType units = 3;

  // Charge and multiplicity
  int32 charge = 4;
  int32 multiplicity = 5;

  // Closed/restricted
  bool closed = 6;
  bool restricted = 7;
}

message JobInput {
  // RETIRED TAGS: 5, 6, 18, 19

  // Molecule
  Mol mol = 1;

  // Run type, enumeration matching current params.cpp definition (commit c807b1f)
  enum RunType {
    ENERGY = 0;
    GRADIENT = 1;
    COUPLING = 14;
    TDCI = 16;
    CI_VEC_OVERLAP = 19;

  }
  RunType run = 2; // Defaults to 0 (ENERGY) in proto3

  // Method type, enumeration matching current params.cpp definition (commit 7fbc9c3)
  // Note this is not complete, the list in comments does not match the code
  enum MethodType {
    option allow_alias = true; // Allow multiple keywords to match the same enum value
    HF = 0;
    CASE = 2;
    SVWN1 = 3;
    SVWN3 = 4;
    SVWN5 = 5;
    SVWN = 5;
    B3LYP1 = 6;
    B3LYP = 6;
    B3LYP3 = 7;
    B3LYP5 = 8;
    BLYP = 9;
    BHANDHLYP = 10;
    PBE = 11;
    REVPBE = 12;
    PBE0 = 13;
    REVPBE0 = 14;
    WPBE = 15;
    WPBEH = 16;
    BOP = 17;
    MUBOP = 18;
    CAMB3LYP = 19;
    B97 = 20;
    WB97 = 21;
    WB97X = 22;
    WB97XD3 = 23;
    GFNXTB = 24;
    GFN2XTB =25;
  }
  MethodType method = 3; // Defaults to 0 (HF) in proto3

  // Basis
  string basis = 4;

  // User specified TeraChem options
  // Will be stored just as "key", "value" sequentially
  repeated string user_options = 7;

  // MO Guess
  // Tags 5&6 were used for guess_mo_coeffs_a/b in r0.2.0 and earlier
  string orb1afile = 8; // If restricted, only fill this one
  string orb1bfile = 9;

  // OUTPUT REQUESTS
  bool return_bond_order = 16; // Want Meyer bond order matrix in output

  // Job specific inputs
  // CI_VEC_OVERLAP
  // Requires a second geometry
  // Also requires 2 CI vector files, a second set of orbital files, and all CAS options
  // The latter are not explicitly defined since they are just strings (handled by user_options)
  repeated double xyz2 = 17;

  // CAS specific options
  // Tags 18 & 19 were used to specify target state and mults, now I just report everything

  // IMD specific
  enum ImdType {
    NOT_IMD = 0;
    IMD_NEW_CONDITION = 1;
    IMD_CONTINUE = 2;
    IMD_HESSIAN = 3;
  }
  ImdType imd_type = 20; // Defaults to 0 (NOT_IMD) in proto3
  int32 imd_initial_orbital = 21;
  enum ImdOrbitalType {
    NO_ORBITAL = 0;
    ALPHA_ORBITAL = 1;
    BETA_ORBITAL = 2;
    ALPHA_DENSITY = 3;
    BETA_DENSITY = 4;
    WHOLE_C = 5;
  }
  ImdOrbitalType imd_orbital_type = 27;
  repeated double imd_xyz_previous = 22;
  repeated float imd_mo_previous = 23;
  repeated float imd_mmatom_position = 24;
  repeated float imd_mmatom_info = 25;
  enum ImdAdditionalOption {
    IMD_NORMAL_MD = 0;
    IMD_MECI_OPT_GRADIENT = 1;
  }
  ImdAdditionalOption imd_additional_option = 26;
}

message JobOutput {
  // RETIRED TAGS: 7, 8, 23, 24

  // Send molecule back
  Mol mol = 1;

  // Energy (run dependent)
  repeated double energy = 2;

  // Gradient
  repeated double gradient = 3;

  //Atomic charge and spin
  repeated double charges = 4;
  repeated double spins = 5;

  //Dipoles, packed as Dx,Dy,Dz,|D|
  repeated double dipoles = 6;

  //Job directory, so the user can go get more info if they want
  string job_dir = 9;
  string job_scr_dir = 10;
  int32 server_job_id = 11;

  //MO coefficients
  // Tags 7 & 8 were used for mo_coeffs_a/b in r0.2.0 and earlier
  string orb1afile = 12; //If restricted, only fill this one
  string orb1bfile = 13;
  int32 orb_size = 14;

  //Bond order matrix
  repeated double bond_order = 16;

  // CI_VEC_OVERLAP
  repeated double ci_overlaps = 17;
  int32 ci_overlap_size = 18;

  // CAS specific output
  // States/mult will just match input
  repeated int32 cas_energy_states = 19;
  repeated int32 cas_energy_mults = 20;
  repeated double cas_transition_dipole = 22;

  //Job specific output
  // COUPLING
  repeated double nacme = 21;

  //MO energies and coefficients
  // Tags 23 & 24 were used for orb_energies/occupations in an earlier commit
  repeated double orba_energies = 25;
  repeated double orbb_energies = 26;
  repeated double orba_occupations = 27;
  repeated double orbb_occupations = 28;

  // CIS specific output
  int32 cis_states = 29;
  repeated double cis_unrelaxed_dipoles = 30;
  repeated double cis_relaxed_dipoles = 31;
  repeated double cis_transition_dipoles = 32;

  // TDCI specific output
  repeated double ci_vec_re = 33;
  repeated double ci_vec_im = 34;

  // IMD specific
  repeated uint32 compressed_bond_order = 35;
  repeated float compressed_hessian = 36;
  repeated float compressed_ao_data = 37;
  repeated float compressed_primitive_data = 38;
  repeated float compressed_mo_vector = 39;
  repeated float imd_mmatom_gradient = 40;
}
