package com.pixelized.shared.lwa.model.alteration

import com.pixelized.shared.lwa.parser.expression.Expression
import com.pixelized.shared.lwa.parser.expression.ExpressionParser

class AlterationJsonFactory(
    private val expressionParser: ExpressionParser,
) {

    fun convertFromJson(
        json: AlterationJson,
    ): Alteration {
        return when (json) {
            is AlterationJsonV1 -> convertFromJsonV1(json = json)
        }
    }

    fun convertFromJsonV1(
        json: AlterationJsonV1,
    ): Alteration {
        return Alteration(
            id = json.id,
            metadata = convertFromJsonV1(json = json.metadata),
            tags = json.tags ?: emptyList(),
            fields = json.fields.map { convertFromJsonV1(json = it) }
        )
    }

    fun convertFromJsonV1(
        json: AlterationJsonV1.AlterationMetadataJsonV1,
    ): Alteration.MetaData {
        return Alteration.MetaData(
            name = json.name,
            description = json.description,
            icon = json.icon,
        )
    }

    fun convertFromJsonV1(
        json: AlterationJsonV1.FieldJsonV1,
    ): Alteration.Field {
        return Alteration.Field(
            fieldId = json.fieldId,
            expression = expressionParser.parse(json.expression) ?: Expression.Flat(0),
        )
    }

    fun convertToJson(
        data: Alteration,
    ): AlterationJson {
        return AlterationJsonV1(
            id = data.id,
            metadata = convertToJson(data = data.metadata),
            tags = data.tags,
            fields = data.fields.map { convertToJson(data = it) },
        )
    }

    fun convertToJson(
        data: Alteration.MetaData,
    ): AlterationJsonV1.AlterationMetadataJsonV1 {
        return AlterationJsonV1.AlterationMetadataJsonV1(
            name = data.name,
            description = data.description,
            icon = data.icon,
        )
    }

    fun convertToJson(
        data: Alteration.Field,
    ): AlterationJsonV1.FieldJsonV1 {
        return AlterationJsonV1.FieldJsonV1(
            fieldId = data.fieldId,
            expression = data.expression.toString(),
        )
    }
}