// Type definitions for @pipcook/boa

type BytesObject = any;
type KeywordArguments = any;
type WithStmtCallback = (ctx: PyObject) => any;

// Boa Interface
declare const GetOwnershipSymbol: unique symbol;
declare const PyGetAttrSymbol: unique symbol;
declare const PySetAttrSymbol: unique symbol;
declare const PyGetItemSymbol: unique symbol;
declare const PySetItemSymbol: unique symbol;

/**
 * Python Object.
 */
declare interface PyObject {
  /**
   * returns the string representation of the python object.
   */
  toString(): string;
  /**
   * returns the JSON object.
   */
  toJSON(): object;
  /**
   * Shortcut for slicing object.
   * @param start 
   * @param end 
   * @param step 
   */
  slice(start?: number, end?: number, step?: number): PyObject;
  /**
   * Get the ownership of this object for main thread.
   */
  [GetOwnershipSymbol](): any;
  /**
   * Get the attribute of this python object.
   * @param k 
   */
  [PyGetAttrSymbol](k: any): any;
  /**
   * Set the attribute of this python object.
   * @param k 
   * @param v 
   */
  [PySetAttrSymbol](k: any, v: any): any;
  /**
   * Get the item of this python object.
   * @param k 
   */
  [PyGetItemSymbol](k: any): any;
  /**
   * Set the item of this python object.
   * @param k 
   * @param v 
   */
  [PySetItemSymbol](k: any, v: any): any;

  // The followings are Proxy-related fields.
  // TODO(Yorkie): returns the specific types.
  /**
   * Proxy object access.
   */
  [key: string]: any;
  /**
   * Proxy array access.
   */
  [key: number]: any;
  /**
   * Proxy function call.
   */
  (...args: any[]): any;
}

/**
 * https://docs.python.org/3.8/library/functions.html#func-list
 */
declare interface PyBuiltins extends PyObject {
  // TODO(Yorkie): generated by Python interface.
}

/**
 * This is a wrapper for shared Python object, just like
 * v8's `SharedArrayBuffer`.
 */
declare class SharedObject {
  constructor(o: PyObject);
}

interface BoaInterface {
  /**
   * Reset the Python module environment, it clears the `sys.modules`, and
   * add the given search paths if provided.
   * @param extraSearchPath 
   */
  setenv(extraSearchPath: string): void;
  /**
   * Import a Python module.
   * @param name the module name.
   */
  import(name: string): PyObject;
  /**
   * Get the builtins
   */
  builtins(): PyBuiltins;
  /**
   * Create a bytes object.
   * @param data the input data.
   */
  bytes(data: string): BytesObject;
  /**
   * Create a keyword arguments objects.
   * @param input the kwargs input.
   */
  kwargs(input: object): KeywordArguments;
  /**
   * With-statement function, See:
   * https://docs.python.org/3/reference/compound_stmts.html#the-with-statement
   * @param ctx
   * @param fn
   */
  with(ctx: PyObject, fn: WithStmtCallback): Promise<any>;
  /**
   * Evaluate a Python expression.
   * @param strs the template string.
   * @param args 
   */
  eval(strs: TemplateStringsArray | string[] | string, ...args: any[]): PyObject;

  // internal interfaces.
  symbols: {
    GetOwnershipSymbol: typeof GetOwnershipSymbol;
    PyGetAttrSymbol: typeof PyGetAttrSymbol;
    PySetAttrSymbol: typeof PySetAttrSymbol;
    PyGetItemSymbol: typeof PyGetItemSymbol;
    PySetItemSymbol: typeof PySetItemSymbol;
  };
  SharedObject: typeof SharedObject;
}

declare const api: BoaInterface;
export = api;
