/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow strict
 */

import type { NodePath } from '@babel/traverse';

import * as t from '@babel/types';
import StateManager from './state-manager';

export type StyleObject = {
  [key: string]: string | null | boolean,
};

declare export class ConditionalStyle {
  test: t.Expression;
  primary: ?StyleObject;
  fallback: ?StyleObject;
  constructor(
    test: t.Expression,
    primary: ?StyleObject,
    fallback: ?StyleObject,
  ): void;
}

export type ResolvedArg = ?StyleObject | ConditionalStyle;
export type ResolvedArgs = $ReadOnlyArray<ResolvedArg>;

export type ResolveStyle = (
  path: NodePath<t.Expression>,
) => null | StyleObject | 'other';

export type ResolveStylexArgumentsResult = {
  resolvedArgs: ResolvedArgs,
  bailOut: boolean,
  bailOutIndex: ?number,
  conditionalCount: number,
};

declare export function resolveStylexArguments(
  argsPaths: $ReadOnlyArray<NodePath<>>,
  resolveStyle: ResolveStyle,
  options?: {
    allowStylePath?: (path: NodePath<>) => boolean,
  },
): ResolveStylexArgumentsResult;

declare export function collectStyleVarsToKeep(
  argumentPaths: $ReadOnlyArray<NodePath<>>,
  state: StateManager,
  options: {
    bailOutIndex: ?number,
    evaluateMemberExpression: (
      path: NodePath<t.MemberExpression>,
    ) => $ReadOnly<{
      confident: boolean,
      value: any,
      ...
    }>,
    isProxyStyle?: (value: any) => boolean,
  },
): void;

declare export function makeConditionalExpression(
  values: ResolvedArgs,
  buildResult: (styles: $ReadOnlyArray<?StyleObject>) => t.Expression,
): t.Expression;
