/**
 * 将一行字符串切割为(str,quoted)[]的形式
 * @param str
 * @returns
 */
export function splitStr2Objs(str: string) {
  // console.log(`splitStr2Objs: ${str}`);
  
  let res: { str: string; isQuoted?: boolean; isSquared?: boolean, isRounded?: boolean }[] = [];
  let len = str.length;
  let p = 0;
  while (p < len) {
    while (p < len && str[p] === " ") ++p; // find first not space
    if (p === len) return res;
    if (str[p] === '"') {
      // find next `"`
      let q = p + 1;
      while (q < len && str[q] !== '"') {
        if (str[q] === "\\") q += 2;
        else ++q;
      }
      if (q >= len) throw "Quote not completed";
      let resstr = str.slice(p + 1, q);
      //   console.log(`Transformed[${res.length}]:\n${transformStr(resstr)}`);
      let transformedStr: string = "error";
      try {
        transformedStr = transformStr(resstr);
      } catch (e) {
        throw "该字符串中的转义字符有错误：" + resstr;
      }
      res.push({ str: transformedStr!, isQuoted: true });
      p = q + 1;
    } else if (str[p] === "[") {
      // find next `]`
      let q = p + 1;
      while (q < len && str[q] !== "]") {
        // if (str[q] === "\\") q += 2;
        // else ++q;
        ++q;
      }
      if (q >= len) throw "square brackets not completed";
      let resstr = str.slice(p + 1, q);
      res.push({ str: resstr, isSquared: true });
      p = q + 1;
    } else if (str[p] === "(") {
      // find next `)`
      let q = p + 1;
      while (q < len && str[q] !== ")") {
        // if (str[q] === "\\") q += 2;
        // else ++q;
        ++q;
      }
      if (q >= len) throw "round brackets not completed";
      let resstr = str.slice(p + 1, q);
      res.push({ str: resstr, isRounded: true });
      p = q + 1;
    }
     else {
      let q = p + 1;
      while (q < len && str[q] !== " " && str[q] !== '"' && str[q] !== "(" && str[q] !== "[") ++q; // find first space/quote after this
      let resstr = str.slice(p, q);
      //   console.log(transformStr(resstr));
      res.push({ str: resstr, isQuoted: false });
      p = q;
    }
  }
  return res;
}

export function mergeObjs2Str(
  objs: { str: string; isQuoted?: boolean; isSquared?: boolean, isRounded?: boolean }[]
) {
  return objs
    .map((obj) =>
      obj.isQuoted ? `"${obj.str}"` : obj.isSquared ? `[${obj.str}]` : obj.isRounded ? `(${obj.str})` : obj.str
    )
    .join(" ");
}

export function splitStr2Strs(str: string) {
  return splitStr2Objs(str).map((obj) =>
    obj.isQuoted ? `"${obj.str}"` : obj.str
  );
}

/**
 * 转义一遍字符串，使其中\n等变成对应字符（可能报错）
 * @param str
 * @returns
 */
export function transformStr(str: string) {
  return JSON.parse(`"${str}"`);
}

// 翻译hzengine script插值字符串
// 语法："...[expression]..."
// 如果希望在字符串中显示`[`，请使用两个`[`，如`"[[正常显示而不被当作表达式的文字]]"`
export function parseInterpolatedStr(str: string): ParsedInterpolationItem[] {
  let len = str.length;
  let p = 0;
  let expr_record: [l: number, r: number][] = [];
  while (p < len) {
    // 寻找第一个`[`
    while (p < len && str[p] !== "[") ++p;
    if (p >= len) break;
    // 判断是否是两个`[`
    if (str[p] === "[" && str[p + 1] === "[") {
      p += 2;
      continue;
    }
    // 寻找第一个`]`
    let q = p + 1;
    while (q < len && str[q] !== "]") {
      ++q;
      // 判断是否是两个`]`
      while (q < len && str[q] === "]" && str[q + 1] === "]") {
        q += 2;
      }
    }
    if (q >= len) {
      // 没有找到`]`，报错
      throw `Interpolated string lose closing bracket: ${str}`;
    }
    expr_record.push([p, q]);
    p = q + 1;
  }
  let left = 0,
    right = len;
  let res: ParsedInterpolationItem[] = [];
  for (let i = 0; i < expr_record.length; ++i) {
    let [l, r] = expr_record[i];
    if (l > left) res.push({ str: str.slice(left, l), isExpression: false });
    res.push({ str: str.slice(l + 1, r), isExpression: true });
    left = r + 1;
  }
  if (left < right)
    res.push({ str: str.slice(left, right), isExpression: false });
  return res;
}

export function removeComment(str: string) {
  let quoteNotClosed = false;
  let len = str.length;
  for (let i = 0; i < len; ++i) {
    if (quoteNotClosed && str[i] === `\\`) {
      ++i;
    } else if (str[i] === `"`) {
      quoteNotClosed = !quoteNotClosed;
    } else if (str[i] === "#" && !quoteNotClosed) {
      return str.slice(0, i);
    }
  }
  return str;
}

type ParsedInterpolationItem = {
  str: string;
  isExpression: boolean;
};
