import { SchemaType } from '@latticexyz/schema-type/deprecated';
import { SchemaAbiType } from '@latticexyz/schema-type/internal';

declare module "prettier-plugin-solidity" {}

interface AbsoluteImportDatum {
    symbol: string;
    path: string;
}
interface RelativeImportDatum {
    symbol: string;
    fromPath: string;
    usedInPath: string;
}
type ImportDatum = AbsoluteImportDatum | RelativeImportDatum;
interface StaticResourceData {
    /** Table namespace string */
    namespace: string;
    /** Table name string */
    name: string;
    /** Whether the table is offchain only (does not use storage) */
    offchainOnly: boolean;
}
interface RenderType {
    /** Fully-qualified name of the user-defined type (may include a library name as prefix) */
    typeId: string;
    /** Fully-qualified name of the user-defined type (may include a library name as prefix), followed by location (none/memory/storage) */
    typeWithLocation: string;
    /** The name of the enum element in SchemaType to use for schema registration (e.g. "UINT256_ARRAY") */
    enumName: string;
    staticByteLength: number;
    isDynamic: boolean;
    /** Empty for internal types. Custom `wrap` method for user defined types. */
    typeWrap: string;
    /** Empty for internal types. Custom `unwrap` method for user defined types. */
    typeUnwrap: string;
    /** Data to generate the custom wrapper and unwrapper if necessary. */
    typeWrappingData?: RenderFieldTypeWrappingData;
    /** Same as typeId for internal types. The underlying `typeId` for user defined types. */
    internalTypeId: string;
}
interface RenderKeyTuple extends RenderType {
    name: string;
    isDynamic: false;
}
interface RenderField extends RenderType {
    arrayElement: RenderType | undefined;
    name: string;
}
interface RenderStaticField extends RenderField {
    isDynamic: false;
}
interface RenderDynamicField extends RenderField {
    isDynamic: true;
}
type RenderFieldTypeWrappingData = {
    kind: "staticArray";
    elementType: string;
    staticLength: number;
};
interface RenderEnum {
    name: string;
    memberNames: string[];
}

/**
 * Common header for all codegenerated solidity files
 */
declare const renderedSolidityHeader = "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.24;\n\n/* Autogenerated file. Do not edit manually. */";
/**
 * Renders a list of lines
 */
declare function renderList<T>(list: T[], renderItem: (item: T, index: number) => string): string;
/**
 * Renders a comma-separated list of arguments for solidity functions, ignoring empty and undefined ones
 */
declare function renderArguments(args: (string | undefined)[]): string;
interface RenderedCommonData {
    /** `_tableId` variable prefixed with its type (empty string if absent) */
    _typedTableId: string;
    /** Comma-separated table key names prefixed with their types (empty string if 0 keys) */
    _typedKeyArgs: string;
    /** Definition and initialization of the dynamic `_keyTuple` bytes32 array */
    _keyTupleDefinition: string;
}
/**
 * Renders some solidity statements commonly used within table libraries
 * @param param0.staticResourceData static data about the table library
 * @param param0.keyTuple key tuple of the table library
 * @returns Rendered statement strings
 */
declare function renderCommonData({ staticResourceData, keyTuple, }: {
    staticResourceData?: StaticResourceData;
    keyTuple: RenderKeyTuple[];
}): RenderedCommonData;
/** For 2 paths which are relative to a common root, create a relative import path from one to another */
declare function solidityRelativeImportPath(fromPath: string, usedInPath: string): string;
/**
 * Aggregates, deduplicates and renders imports for symbols per path.
 * Identical symbols from different paths are NOT handled, they should be checked before rendering.
 */
declare function renderImports(imports: ImportDatum[]): string;
/**
 * Aggregates, deduplicates and renders imports for symbols per path.
 * Identical symbols from different paths are NOT handled, they should be checked before rendering.
 */
declare function renderRelativeImports(imports: RelativeImportDatum[]): string;
/**
 * Aggregates, deduplicates and renders imports for symbols per path.
 * Identical symbols from different paths are NOT handled, they should be checked before rendering.
 */
declare function renderAbsoluteImports(imports: AbsoluteImportDatum[]): string;
interface RenderWithStoreCallbackData {
    /** `_store` variable prefixed with its type (undefined if library name) */
    _typedStore: string | undefined;
    /**  `_store` variable (undefined if library name) */
    _store: string;
    /** Empty string if storeArgument is false, otherwise `" (using the specified store)"` */
    _commentSuffix: string;
    /** Prefix to differentiate different kinds of store usage within methods */
    _methodNamePrefix: string;
    /** Whether FieldLayout variable should be passed to store methods */
    _useExplicitFieldLayout?: boolean;
}
/**
 * Renders several versions of the callback's result, which access Store in different ways
 * @param storeArgument whether to render a version with `IStore _store` as an argument
 * @param callback renderer for a method which uses store
 * @returns Concatenated results of all callback calls
 */
declare function renderWithStore(storeArgument: boolean, callback: (data: RenderWithStoreCallbackData) => string): string;
/**
 * Renders several versions of the callback's result, which have different method name suffixes
 * @param withSuffixlessFieldMethods whether to render methods with an empty suffix
 * @param fieldName name of the field which the methods access, used for a suffix
 * @param callback renderer for a method to be suffixed
 * @returns Concatenated results of all callback calls
 */
declare function renderWithFieldSuffix(withSuffixlessFieldMethods: boolean, fieldName: string, callback: (_methodNameSuffix: string) => string): string;
/**
 * Renders `_tableId` definition of the given table.
 * @param param0 static resource data needed to construct the table ID
 */
declare function renderTableId({ namespace, name, offchainOnly, }: Pick<StaticResourceData, "namespace" | "name" | "offchainOnly">): string;
/**
 * Renders solidity typecasts to get from the given type to `bytes32`
 * @param name variable name to be typecasted
 * @param param1 type data
 */
declare function renderValueTypeToBytes32(name: string, { typeUnwrap, internalTypeId }: Pick<RenderType, "typeUnwrap" | "internalTypeId">): string;
/**
 * Whether the storage representation of the given solidity type is left aligned
 */
declare function isLeftAligned(field: Pick<RenderType, "internalTypeId">): boolean;
/**
 * The number of padding bits in the storage representation of a right-aligned solidity type
 */
declare function getLeftPaddingBits(field: Pick<RenderType, "internalTypeId" | "staticByteLength">): number;

/**
 * Render a list of enum data as solidity enum definitions
 */
declare function renderEnums(enums: RenderEnum[]): string;

/**
 * Renders the necessary helper functions to typecast to/from the types of given fields and keys
 */
declare function renderTypeHelpers(options: {
    fields: RenderField[];
    keyTuple: RenderKeyTuple[];
}): string;

declare const schemaTypesToRecsTypeStrings: Record<SchemaType, string>;

interface ContractInterfaceFunction {
    name: string;
    parameters: string[];
    stateMutability: string;
    returnParameters: string[];
}
interface ContractInterfaceError {
    name: string;
    parameters: string[];
}
interface SymbolImport {
    symbol: string;
    path: string;
}
/**
 * Parse the contract data to get the functions necessary to generate an interface,
 * and symbols to import from the original contract.
 * @param data contents of a file with the solidity contract
 * @param contractName name of the contract
 * @returns interface data
 */
declare function contractToInterface(data: string, contractName: string): {
    functions: ContractInterfaceFunction[];
    errors: ContractInterfaceError[];
    symbolImports: SymbolImport[];
};

interface SolidityUserDefinedType {
    /** Fully-qualified name of the user-defined type (may include a library name as prefix) */
    typeId: string;
    /** Name of the wrapped primitive type */
    internalTypeId: string;
    /** Symbol which must be imported to use the type (either the type name, or the library name where the type is defined) */
    importSymbol: string;
    /** Path to the solidity file which contains the user type */
    fromPath: string;
    /** Whether `fromPath` is relative  */
    isRelativePath: boolean;
}
/**
 * Parse the solidity data to extract user-defined type information.
 * @param data contents of a solidity file with the user types declarations
 * @param userTypeNames names of the user types to extract
 * @param fromPath path to the solidity file from which the user types are extracted
 * @returns record of type names mapped to the extracted type information
 */
declare function extractUserTypes(data: string, userTypeNames: string[], fromPath: string): Record<string, SolidityUserDefinedType>;

/**
 * Formats solidity code using prettier
 * @param content solidity code
 * @param prettierConfigPath optional path to a prettier config
 * @returns formatted solidity code
 */
declare function formatSolidity(content: string, prettierConfigPath?: string): Promise<string>;
/**
 * Formats typescript code using prettier
 * @param content typescript code
 * @returns formatted typescript code
 */
declare function formatTypescript(content: string): Promise<string>;

/**
 * Formats solidity code using prettier and write it to a file
 * @param output solidity code
 * @param fullOutputPath full path to the output file
 * @param logPrefix prefix for debug logs
 */
declare function formatAndWriteSolidity(output: string, fullOutputPath: string, logPrefix: string): Promise<void>;
/**
 * Formats typescript code using prettier and write it to a file
 * @param output typescript code
 * @param fullOutputPath full path to the output file
 * @param logPrefix prefix for debug logs
 */
declare function formatAndWriteTypescript(output: string, fullOutputPath: string, logPrefix: string): Promise<void>;

type UserType = {
    filePath: string;
    internalType: SchemaAbiType;
};
/**
 * Load the user type files and extract type information from them.
 * @param userTypes record of user type data mapped by type names
 * @param outputBaseDirectory base path to the output directory
 * @param remappings solc remappings
 * @returns record of the user type information mapped by type names
 */
declare function loadAndExtractUserTypes(userTypes: Record<string, UserType>, outputBaseDirectory: string, remappings: [string, string][]): Record<string, SolidityUserDefinedType>;

/**
 * Explicitly normalize a given path to a posix path (using `/` as separator).
 * This should be used for generating Solidity files that will be consumed by solc,
 * because solc expects `/` as path separator, but path.join produces `\` if the user is on windows.
 */
declare function posixPath(path: string): string;

export { AbsoluteImportDatum, ContractInterfaceError, ContractInterfaceFunction, ImportDatum, RelativeImportDatum, RenderDynamicField, RenderEnum, RenderField, RenderFieldTypeWrappingData, RenderKeyTuple, RenderStaticField, RenderType, SolidityUserDefinedType, StaticResourceData, UserType, contractToInterface, extractUserTypes, formatAndWriteSolidity, formatAndWriteTypescript, formatSolidity, formatTypescript, getLeftPaddingBits, isLeftAligned, loadAndExtractUserTypes, posixPath, renderAbsoluteImports, renderArguments, renderCommonData, renderEnums, renderImports, renderList, renderRelativeImports, renderTableId, renderTypeHelpers, renderValueTypeToBytes32, renderWithFieldSuffix, renderWithStore, renderedSolidityHeader, schemaTypesToRecsTypeStrings, solidityRelativeImportPath };
