/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

// The enclosing bootstrap supplies call/emit; neither is exposed to model code.
const ErrorClass = Error;
const stringify = JSON.stringify;
const output = (value) => {
  const error = emit(value);
  if (error) throw new ErrorClass(error.message);
};
const write = (value) =>
  output({
    kind: 'text',
    text: typeof value === 'string' ? value : (stringify(value) ?? 'undefined'),
  });
const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
const decode = (value) => {
  const padding = value.endsWith('==') ? 2 : value.endsWith('=') ? 1 : 0;
  const result = new Uint8Array(Math.floor((value.length * 3) / 4) - padding);
  let offset = 0;
  let bits = 0;
  let buffer = 0;
  for (const ch of value) {
    if (ch === '=') break;
    const n = alphabet.indexOf(ch);
    if (n < 0) throw new ErrorClass('Invalid base64 image');
    buffer = (buffer << 6) | n;
    bits += 6;
    if (bits >= 8) {
      bits -= 8;
      result[offset++] = (buffer >> bits) & 255;
    }
  }
  return result;
};
const encode = (bytes) => {
  let result = '';
  for (let i = 0; i < bytes.length; i += 3) {
    const n = (bytes[i] << 16) | ((bytes[i + 1] ?? 0) << 8) | (bytes[i + 2] ?? 0);
    result +=
      alphabet[(n >> 18) & 63] +
      alphabet[(n >> 12) & 63] +
      (i + 1 < bytes.length ? alphabet[(n >> 6) & 63] : '=') +
      (i + 2 < bytes.length ? alphabet[n & 63] : '=');
  }
  return result;
};
const emitImage = async (value) => {
  let image;
  if (typeof value === 'string') {
    const match = /^data:(image\/(?:png|jpeg|webp));base64,([A-Za-z0-9+/]+=*)$/.exec(value);
    if (!match)
      throw new ErrorClass(
        'Expected an image data URL; filesystem and URL fetching are unavailable',
      );
    image = { type: 'image', mimeType: match[1], data: match[2] };
  } else if (value?.type === 'image') {
    image = { type: 'image', mimeType: value.mimeType, data: value.data };
  } else {
    const bytes = value instanceof Uint8Array ? value : value?.bytes;
    if (!(bytes instanceof Uint8Array))
      throw new ErrorClass('Expected image bytes or an image content block');
    const mimeType =
      value.mimeType ??
      (bytes[0] === 137 ? 'image/png' : bytes[0] === 255 ? 'image/jpeg' : 'image/webp');
    image = { type: 'image', mimeType, data: encode(bytes) };
  }
  output({ kind: 'media', content: image });
};
const invoke = async (method, args = {}) => {
  const result = await call('cua', { method, ...args });
  if (!result.ok) throw new ErrorClass(result.error.message);
  return result.value;
};
let documented = false;
let reference;
const documentation = async () => {
  const text = await invoke('documentation');
  if (!documented || reference !== text) {
    reference = text;
    write(text);
    documented = true;
  }
  return text;
};
const observation = async (method, options = {}) => {
  const value = await invoke(method, { options });
  await documentation();
  if (options.emit !== false) write(value);
  else if (value?.errors?.length) write({ errors: value.errors });
  return value;
};
const bind = async (method, args) => {
  const result = await invoke(method, args);
  await documentation();
  const handle = result.handle;
  const observe = async (kind, options = {}) => {
    const value = await invoke('observe', { handle, kind, options });
    if (options.emit !== false) {
      if (value.state !== undefined) write(value.state);
      if (value.image) await emitImage(value.image);
    }
    const screenshot = value.image ? decode(value.image.data) : undefined;
    return kind === 'ax'
      ? value.state
      : kind === 'screenshot'
        ? screenshot
        : { state: value.state, screenshot };
  };
  const action = (kind, args) =>
    invoke('action', { handle, action: { kind, ...args } }).then((result) => {
      if (result?.warning) write(result.warning);
      if (['unverifiable', 'unchanged', 'partial', 'suspected_noop'].includes(result?.effect))
        write({
          effect: result.effect,
          route: result.route,
          delivery: result.delivery,
          requestedChars: result.requested_chars,
          deliveredChars: result.delivered_chars,
          warning: result.guidance,
        });
    });
  const target = {
    getAXState: (options) => observe('ax', options),
    getScreenshot: (options) => observe('screenshot', options),
    getAXStateAndScreenshot: (options) => observe('both', options),
    click: (target, options = {}) => action('click', { target, options }),
    moveCursor: (target) => invoke('action', { handle, action: { kind: 'moveCursor', target } }),
    drag: (from, to) => action('drag', { from, to }),
    scroll: (target, direction, distance) => action('scroll', { target, direction, distance }),
    setValue: (index, value) => action('setValue', { index, value }),
    selectText: (index, text, options = {}) => action('selectText', { index, text, options }),
    performSecondaryAction: (index, action) => action('secondary', { index, action }),
  };
  if (result.kind === 'tab') {
    Object.assign(target, {
      id: result.id,
      typeText: (index, text) => action('typeText', { index, text }),
      paste: (index, text, options = {}) => action('paste', { index, text, options }),
      pressKey: (index, key) => action('pressKey', { index, key }),
      goto: (url) => action('navigate', { url }),
      back: () => action('back', {}),
      forward: () => action('forward', {}),
      reload: () => action('reload', {}),
      close: () => action('close', {}),
    });
  } else {
    Object.assign(target, {
      typeText: (text) => action('typeText', { text }),
      paste: (text, options = {}) => action('paste', { text, options }),
      pressKey: (key) => action('pressKey', { key }),
    });
  }
  write(result.state);
  return Object.freeze(target);
};
Object.defineProperty(globalThis, 'nodeRepl', { value: Object.freeze({ write, emitImage }) });
Object.defineProperty(globalThis, 'cua', {
  value: Object.freeze({
    computer: Object.freeze({
      target: nativePlatform,
      ...(nativePlatform === 'windows'
        ? { launch_app: (input) => invoke('launchApp', { app: input.app }).then(() => {}) }
        : {}),
    }),
    cursor: Object.freeze({
      configure: (options = {}) => invoke('configureCursor', { options }),
      getState: () => observation('cursorState'),
    }),
    getState: (options) => observation('getState', options),
    listApps: (options) => observation('listApps', options),
    listWindows: (options) => observation('listWindows', options),
    getApp: (target) => bind('getApp', { target }),
    listBrowsers: (options) => observation('listBrowsers', options),
    listTabs: (options) => observation('listTabs', options),
    getBrowser: async (options = {}) => {
      const result = await invoke('getBrowser', { options });
      await documentation();
      return Object.freeze({ browserId: result.id, documentation });
    },
    getTab: (reference, options = {}) => bind('getTab', { reference, options }),
    createBrowserTab: (browserId, url = 'about:blank', options = {}) =>
      bind('createBrowserTab', { browserId, url, options }),
    rewriteDocumentation: async () => {
      documented = false;
      return documentation();
    },
  }),
});
