/**
 * @typedef YosysRawNet
 * @property {string} creator JSON 的创建者信息，通常是 Yosys 的版本和构建详情。
 * @property {Record<string, YosysNetModule>} modules 模块名称到模块定义的映射。
 * @property {Record<string, YosysModel>} [models] 模型定义的映射（仅在使用 `-aig` 选项时存在）。
 */

import { Module } from "./render/layout";

/**
 * @typedef {number | string} WireId 信号ID
 */

/**
 * @typedef {'input' | 'output' | 'inout'} PortDirection
 */

/**
 * @typedef {string} ParameterValue 参数值，一般表示为二进制的字符串，比如 "00000000000000000000000000001000" 表示 8
 */

/**
 * @typedef YosysNetModule
 * @property {ModuleAttribute} attributes 模块的属性，如是否为顶层模块及其源文件。
 * @property {Record<string, ParameterValue>} [parameter_default_values] 参数的默认值。
 * @property {Record<string, YosysPort>} ports 端口名称到端口定义的映射。
 * @property {Record<string, YosysCell>} cells 单元名称到单元定义的映射。
 * @property {Record<string, YosysMemory>} [memories] 内存名称到内存定义的映射。
 * @property {Record<string, YosysNetname>} netnames 信号名称到网络定义的映射。
 * @property {Map<number, YosysMergeWireInfo>} [mergeWireInfos]
 * 
 * 【信号名称】大体分为两种：
 * 1. 普通信号 
 * 2. 中间变量信号
 * 
 * ### 普通信号名
 * 一般是 module 的 port 和 module scope 内定义的各类变量，它们都有自己的名字。
 * 
 * ```json
 *  "A": {
        "hide_name": 0,
        "bits": [ 2 ],
        "attributes": { ... }
    }
 * ```
 * 此处信号名称就是 A，它可能代表当前 module 的一个 port 的名字，也可也是一个内部定义的 wire 或者 reg
 * 
 * ### 中间变量信号
 * 一些操作比如 `assign x = A & B | C` 这样的操作会产生中间变量，比如 A & B 会产生一个中间值，这个中间值在与 C 去发生计算
 * yosys 中使用如下的格式来代表这样的中间变量：
 * 
 * `"${op_name}${define_path}:{define_line}${op_id}_{op_output_name}"`
 * 
 * - `op_name`: 操作名称，比如 `&` 就是 `and`
 * - `define_path`: 发生这个操作的文件路径
 * - `define_line`: 发生这个操作的行
 * - `op_id`: 当前操作在当前 module 内的编号
 * - `op_output_name`: 当前操作的输出值（有的操作会有多个输出，一般只有一个输出的简单操作，输出的 name 都是 Y）
 * 
 * 
 * ```json
 *  "$xor$/home/dide/project/Digital-Test/DIDEtemp/user/src/language/vlog/dependence/utils/utils.v:32$4_Y": {
        "hide_name": 1,
        "bits": [ 11 ],
        "attributes": { ... }
    }
 * ```
 * 
 * 
 */

/**
 * @typedef YosysMergeWireInfo
 * @property {'variable' | 'constant'} type 当前 wire 的类型（变量还是常量）
 * @property {number} width 当前 wire 代表的位宽
 */

/**
 * @typedef ModuleAttribute
 * @property {string} [top] 表示该模块是否为顶层模块（1 表示是，0 表示否）。
 * @property {string} src 模块定义的源文件和行号。
 * @property {string} [cells_not_processed] 代表当前模块是否没有被处理
 * 
 * 比如对于一个 main.v 而言，它内部定义了两个模块 A 和 B。如果只综合了 A，那么 B 也会出现在 yosys json 中
 * 但是 B 的会额外出现 `cells_not_processed` 这个字段，且值为 "00000000000000000000000000000001"，代表没有处理
 * 
 * @property {string} [dynports] 动态端口标志（1 表示是，0 表示否）。
 * @property {string} [hdlname] HDL 名称。
 */

/**
 * @typedef YosysPort 描述一个 module 的 port
 * @property {PortDirection} direction 端口的方向（例如 "input"、"output" 或 "inout"）。
 * @property {WireId[]} bits 当前 port 每一个位置 bit 的信号 ID. bits.length
 * @property {number} [offset] 使用的最低位索引（如果非 0）。
 * @property {number} [upto] 如果端口位索引是 MSB-first，则为 1。
 * @property {number} [signed] 如果端口是有符号的，则为 1。
 */

/**
 * @typedef YosysCell 描述一个基本器件
 * @property {number} hide_name 当前器件是否有具体的名字，如果有则为 1，否则为 0， 加减乘除都是无名器件，一般都为 0，例化模块都是有名字的，一般都为 1
 * @property {string} type 器件的类型，例如 "$_AND_" 代表 yosys 内置的与门， full_adder_1bit 代表当前器件是一个单位全加器的例化模块
 * @property {string} [model] AIG 模型名称（仅在使用 `-aig` 选项时存在）。
 * @property {Record<string, string>} [parameters] 与单元关联的参数（如果有）。
 * @property {CellAttribute} attributes 单元的属性，如源文件和行号。
 * @property {Record<string, PortDirection>} port_directions 端口名称到端口方向的映射（例如 "input"、"output" 或 "inout"）。
 * @property {Record<string, WireId[]>} connections 端口名称到 信号ID 的映射。
 */

/**
 * @typedef CellAttribute
 * @property {string} src 单元定义的源文件和行号。
 */

/**
 * @typedef YosysMemory
 * @property {number} hide_name 是否隐藏内存名称（1 表示是，0 表示否）。
 * @property {Record<string, any>} attributes 内存的属性。
 * @property {number} width 内存的宽度。
 * @property {number} start_offset 最低有效内存地址。
 * @property {number} size 内存的大小。
 */

/**
 * @typedef YosysNetname 一个模块内部的所有变量（port，临时变量等等）
 * @property {number} hide_name 同上
 * @property {WireId[]} bits 与网络名称关联的位索引。
 * @property {number} [offset] 使用的最低位索引（如果非 0）。
 * @property {number} [upto] 如果端口位索引是 MSB-first，则为 1。
 * @property {number} [signed] 如果端口是有符号的，则为 1。
 */

/**
 * @typedef YosysModel
 * @property {Array<Array<any>>} [model_name] AIG 模型的节点列表。
 */

/**
 * @typedef YosysAIGNode
 * @property {string} type 节点类型（例如 "port"、"nport"、"and"、"nand"、"true"、"false"）。
 * @property {string} [portname] 端口名称（如果节点类型为 "port" 或 "nport"）。
 * @property {number} [bitindex] 位索引（如果节点类型为 "port" 或 "nport"）。
 * @property {number} [node_index] 节点索引（如果节点类型为 "and" 或 "nand"）。
 * @property {Array<string>} [out_list] 输出端口名称和位索引的列表。
 */


/**
 * @typedef ElkGraph
 * @property {string} id 图形的唯一标识符。
 * @property {ElkNode[]} children 图形的子节点列表。
 * @property {ElkEdge[]} edges 图形中的边列表。
 * @property {ElkLayoutOptions} [layoutOptions] 图形的布局选项（可选）。
 */

/**
 * @typedef ElkNode
 * @property {string} id 节点的唯一标识符。
 * @property {string} [renderName] node 展示的名字，布局算法前生成
 * @property {'port' | 'cell' | 'instance' | 'constant' | 'cellPort' | 'portConnection'} [renderType] 渲染的类型
 * @property {ElkNode[]} children 当前节点的内部
 * @property {ElkPort[]} ports 当前节点的端口
 * @property {ElkEdge[]} edges 当前节点的连线
 * @property {string} type 节点的类型
 * @property {number} [x] 节点的 X 坐标（可选，由布局算法生成）。
 * @property {number} [y] 节点的 Y 坐标（可选，由布局算法生成）。
 * @property {number} [width] 节点的宽度（可选）。
 * @property {number} [height] 节点的高度（可选）。
 * @property {ElkPort[]} [ports] 节点的端口列表（可选）。
 * @property {ElkLayoutOptions} [layoutOptions] 节点的布局选项（可选）。
 */

/**
 * @typedef ElkPort
 * @property {string} id 端口的唯一标识符。
 * @property {number} [x] 端口的 X 坐标（可选，由布局算法生成）。
 * @property {number} [y] 端口的 Y 坐标（可选，由布局算法生成）。
 * @property {number} [width] 端口的宽度（可选）。
 * @property {number} [height] 端口的高度（可选）。
 * @property {'input' | 'output'} [direction] 端口在这个实体上的方向
 * @property {'port' | 'instance' | 'cell'} [source] 这是谁的端口
 * @property {ElkLayoutOptions} [layoutOptions] 端口的布局选项（可选）。
 */

/**
 * @typedef ElkEdge
 * @property {string} id 边的唯一标识符。
 * @property {string[]} sources 边的源节点列表。
 * @property {string} source 边的源节点。
 * @property {string} sourcePort 边的源节点的port。
 * @property {string[]} targets 边的目标节点列表。
 * @property {string} target 边的目标节点。
 * @property {string} targetPort 边的目标节点的port。
 * @property {string} [orginalSource]
 * @property {string} [orginalTarget]
 * @property {string} [container] 所在容器的 id （可选，由布局算法生成）
 * @property {ElkSection[]} [sections] 具体的连线规则（可选，由布局算法生成）
 * @property {ElkLayoutOptions} [layoutOptions] 边的布局选项（可选）。
 */

/**
 * @typedef ElkPoint
 * @property {number} x
 * @property {number} y
 */

/**
 * @typedef ElkSection
 * @property {ElkPoint} startPoint 起点
 * @property {ElkPoint} endPoint 终点
 * @property {ElkPoint[]} bendPoints 中间经过的点
 * @property {string} id edge 的 id
 * @property {string} incomingShape source 实体的 id
 * @property {string} outgoingShape target 实体的 id
 */

/**
 * @typedef ElkLayoutOptions
 * @property {string} [elk.algorithm] - 布局算法（可选）。
 * @property {string} [elk.direction] - 布局方向（可选，如 "RIGHT", "DOWN" 等）。
 * @property {number} [elk.spacing.nodeNode] - 节点之间的间距（可选）。
 * @property {number} [elk.spacing.edgeNode] - 边与节点之间的间距（可选）。
 * @property {'NORTH' | 'SOUTH' | 'EAST' | 'WEST'} [elk.port.side] - 端口的位置（可选，如 "NORTH", "SOUTH", "EAST", "WEST"）。
 */



/**
 * @typedef BasicD3DataItem
 * @property {string} id 全局唯一标识
 * @property {number} x svg 布局下的 x
 * @property {number} y svg 布局下的 y
 * @property {number} width 宽度
 * @property {number} height 高度
 * @property {string} [fill] 填充颜色
 * @property {string} [text] 填充文字
 * @property {number} [rx]  圆角 rx
 * @property {number} [ry]  圆角 ry
 */

/**
 * @typedef BasicD3ManagmentItem 用于管理一个 实体/连接 的 d3 上下文数据结构
 * @property {'cell' | 'connection' | 'instantiation' | 'port' | 'wire'} type 
 * @property {BasicD3DataItem} data 用于绑定 d3 渲染的数据，【初始化/特殊事件】会使得 d3 去主动根据
 * @property {d3.Selection} selection 渲染成图形对应的 d3 选择集
 * @property {DragContext} [dragContext] 与当前这个 实体 相关的拖拽上下文（目前不支持 wire 和 connection 的）
 */

/**
 * @typedef DragContext
 * @property {ElkGraph} elkGraph 用于更新的最小图
 * @property {DragNeighbor[]} neighbors 当前 selection 代表的节点的邻居
 */

/**
 * @typedef DragNeighbor
 * @property {'port' | 'cell'} type
 * @property {'source' | 'target'} location
 * @property {ElkEdge} edge 构成这个邻居关系的 edge
 * @property {d3.Selection} selection
 * @property {DragConnection[]} connections 如果 type 为 port, 则为空
 */

/**
 * @typedef DragConnection
 * @property {d3.Selection} selection
 */

/**
 * @typedef ElkMakerConfig
 * @param {string} [parentId]
 */