/******************************************************************************
 * 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
 *
 ******************************************************************************/

// this module tests the compiler option '-h', which allows converting
// universal charstrings to charstrings
module unicharstrToCharstr {

function f_init(universal charstring p) return charstring
{
  var charstring x := p;
  return x;
}

function f_assign(universal charstring p) return charstring
{
  var charstring x;
  x := p;
  return x;
}

const universal charstring c_ustr := "xy";

type component CT {}

testcase tc_init_pos() runs on CT {
  var charstring exp := "abc";
  var charstring res := f_init(exp);
  if (res != exp) {
    setverdict(fail, res);
  }
  else {
    setverdict(pass);
  }
}

testcase tc_init_neg() runs on CT {
  @try {
    var charstring res := f_init("áram");
    setverdict(fail, "Error expected.");
  }
  @catch (msg) {
    var template charstring msg_exp := pattern "*Non-ASCII characters cannot be used to initialize a charstring*";
    if (not match(msg, msg_exp)) {
      setverdict(fail, "Invalid error message: ", msg);
    }
    else {
      setverdict(pass);
    }
  }
}

testcase tc_init_const() runs on CT {
  var charstring x := c_ustr;
  if (log2str(x) != log2str(c_ustr)) {
    setverdict(fail, x);
  }
  else {
    setverdict(pass);
  }
}

testcase tc_assign_pos() runs on CT {
  var charstring exp := "abc";
  var charstring res := f_assign(exp);
  if (res != exp) {
    setverdict(fail, res);
  }
  else {
    setverdict(pass);
  }
}

testcase tc_assign_neg() runs on CT {
  @try {
    var charstring res := f_assign("áram");
    setverdict(fail, "Error expected.");
  }
  @catch (msg) {
    var template charstring msg_exp := pattern "*Non-ASCII characters cannot be assigned to a charstring*";
    if (not match(msg, msg_exp)) {
      setverdict(fail, "Invalid error message: ", msg);
    }
    else {
      setverdict(pass);
    }
  }
}

testcase tc_assign_const() runs on CT {
  var charstring x;
  x := c_ustr;
  if (log2str(x) != log2str(c_ustr)) {
    setverdict(fail, x);
  }
  else {
    setverdict(pass);
  }
}

testcase tc_concat_pos() runs on CT {
  var universal charstring v_ustr := "123";
  var charstring v_cstr := "456";
  var charstring v_res := v_ustr & v_cstr;
  var charstring v_exp := "123456";
  if (v_res != v_exp) {
    setverdict(fail, "#1: ", v_res);
  }
  v_res := v_cstr & v_ustr;
  v_exp := "456123";
  if (v_res != v_exp) {
    setverdict(fail, "#2: ", v_res);
  }
  setverdict(pass);
}

testcase tc_concat_neg() runs on CT {
  var universal charstring v_ustr := "123" & char(0, 0, 1, 113);
  var charstring v_cstr := "456";
  var charstring v_res;
  
  @try {
    v_res := v_ustr & v_cstr;
    setverdict(fail, "Error expected (#1).");
  }
  @catch (msg) {
    var template charstring msg_exp := pattern "*Non-ASCII characters cannot be assigned to a charstring*";
    if (not match(msg, msg_exp)) {
      setverdict(fail, "Invalid error message (#1): ", msg);
    }
  }
  
  @try {
    v_res := v_cstr & v_ustr;
    setverdict(fail, "Error expected (#2).");
  }
  @catch (msg) {
    var template charstring msg_exp := pattern "*Non-ASCII characters cannot be assigned to a charstring*";
    if (not match(msg, msg_exp)) {
      setverdict(fail, "Invalid error message (#2): ", msg);
    }
  }
  
  setverdict(pass);
}

testcase tc_concat_const() runs on CT {
  var charstring v_cstr := "ab";
  var charstring v_res := c_ustr & v_cstr;
  var charstring v_exp := "xyab";
  if (v_res != v_exp) {
    setverdict(fail, "#1: ", v_res);
  }
  v_res := v_cstr & c_ustr;
  v_exp := "abxy";
  if (v_res != v_exp) {
    setverdict(fail, "#2: ", v_res);
  }
  setverdict(pass);
}

control {
  execute(tc_init_pos());
  execute(tc_init_neg());
  execute(tc_init_const());
  execute(tc_assign_pos());
  execute(tc_assign_neg());
  execute(tc_assign_const());
  execute(tc_concat_pos());
  execute(tc_concat_neg());
  execute(tc_concat_const());
}

}
