/******************************************************************************
 * Copyright (c) 2000-2025 Ericsson Telecom AB
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
 *
 * Contributors:
 *   Baranyi, Botond – initial implementation
 *
 ******************************************************************************/
module ObjIdTests {

import from Types all;
import from Tools all;

external function enc_objid(in ObjId x) return bitstring with { extension "prototype(convert) encode(PER)" }
external function enc_relobjid(in RelObjId x) return bitstring with { extension "prototype(convert) encode(PER)" }

external function dec_objid(in bitstring x) return ObjId with { extension "prototype(convert) decode(PER)" }
external function dec_relobjid(in bitstring x) return RelObjId with { extension "prototype(convert) decode(PER)" }

testcase tc_per_objid_encode() runs on CT {
  var bitstring enc_exp := '00000011000000000000000100000011'B;
  var bitstring enc := enc_objid(objid_val);
  if (enc != enc_exp) {
    setverdict(fail, "Encoding object identifier #1 failed. Got: ", enc, ", expected: ", enc_exp);
  }
  var ObjId x := objid { 0 0 1 3 }; // same value, expecting the same encoding
  enc := enc_objid(x);
  if (enc != enc_exp) {
    setverdict(fail, "Encoding object identifier #2 failed. Got: ", enc, ", expected: ", enc_exp);
  }
  enc_exp := '000000100000001000000110'B;
  enc := enc_relobjid(rel_objid_val1);
  if (enc != enc_exp) {
    setverdict(fail, "Encoding relative object identifier #1 failed. Got: ", enc, ", expected: ", enc_exp);
  }
  enc_exp := '0000010000000010000001100000110000000001'B;
  enc := enc_relobjid(rel_objid_val2);
  if (enc != enc_exp) {
    setverdict(fail, "Encoding relative object identifier #2 failed. Got: ", enc, ", expected: ", enc_exp);
  }
  setverdict(pass);
}

testcase tc_per_objid_decode() runs on CT {
  var bitstring enc := '00000011000000000000000100000011'B;
  var ObjId x1 := dec_objid(enc);
  if (x1 != objid_val) {
    setverdict(fail, "Decoding object identifier failed. Got: ", x1, ", expected: ", objid_val);
  }
  enc := '000000100000001000000110'B;
  var RelObjId x2 := dec_relobjid(enc);
  if (x2 != rel_objid_val1) {
    setverdict(fail, "Decoding relative object identifier #1 failed. Got: ", x2, ", expected: ", rel_objid_val1);
  }
  enc := '0000010000000010000001100000110000000001'B;
  var RelObjId x3 := dec_relobjid(enc);
  if (x3 != rel_objid_val2) {
    setverdict(fail, "Decoding relative object identifier #2 failed. Got: ", x3, ", expected: ", rel_objid_val2);
  }
  setverdict(pass);
}

testcase tc_per_objid_negtest() runs on CT {
  var ObjId x;
  var bitstring buf;
  @try {
    buf := enc_objid(x);
    setverdict(fail, "Object identifier #1 encoded successfully.");
  }
  @catch (msg) {
    if (not match(msg, pattern "*Encoding an unbound object identifier value.")) {
      setverdict(fail, "Invalid error message received (#1): ", msg);
    }
  }
  buf := ''B;
  @try {
    x := dec_objid(buf);
    setverdict(fail, "Object identifier #2 decoded successfully.");
  }
  @catch (msg) {
    if (not match(msg, pattern "*Buffer overflow while PER-decoding. Requested bits: 1, remaining bits in buffer: 0")) {
      setverdict(fail, "Invalid error message received (#2): ", msg);
    }
  }
  setverdict(pass);
}
  
control {
  execute(tc_per_objid_encode());
  execute(tc_per_objid_decode());
  execute(tc_per_objid_negtest());
}

}
