/*
 * Copyright 2013-2026, Seqera Labs
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package nextflow.trace.config

import groovy.transform.CompileStatic
import nextflow.config.spec.ConfigOption
import nextflow.config.spec.ConfigScope
import nextflow.config.spec.ScopeName
import nextflow.script.dsl.Description
import nextflow.trace.TraceHelper

@ScopeName("trace")
@Description("""
    The `trace` scope controls the layout of the execution trace file generated by Nextflow.
""")
@CompileStatic
class TraceConfig implements ConfigScope {

    private static final List<String> DEF_FIELDS = List.of(
        'task_id',
        'hash',
        'native_id',
        'name',
        'status',
        'exit',
        'submit',
        'duration',
        'realtime',
        '%cpu',
        'peak_rss',
        'peak_vmem',
        'rchar',
        'wchar'
    )

    @ConfigOption
    @Description("""
        Create the execution trace file on workflow completion (default: `false`).
    """)
    final boolean enabled

    @ConfigOption(types=[String])
    @Description("""
        Comma-separated list of [trace fields](https://nextflow.io/docs/latest/tracing.html#trace-report) to include in the report.
    """)
    final List<String> fields

    @ConfigOption
    @Description("""
        Trace file name (default: `'trace-<timestamp>.txt'`).
    """)
    final String file

    @ConfigOption
    @Description("""
        Overwrite any existing trace file with the same name (default: `false`).
    """)
    final boolean overwrite

    @ConfigOption
    @Description("""
        Report trace metrics as raw numbers where applicable, i.e. report duration values in milliseconds and memory values in bytes (default: `false`).
    """)
    final boolean raw

    @ConfigOption
    @Description("""
        Character used to separate values in each row (default: `\\t`).
    """)
    final String sep

    /* required by extension point -- do not remove */
    TraceConfig() {}

    TraceConfig(Map opts) {
        enabled = opts.enabled as boolean
        fields = parseFields(opts.fields)
        file = opts.file ?: defaultFileName()
        overwrite = opts.overwrite as boolean
        raw = opts.raw as boolean
        sep = opts.sep ?: '\t'
    }

    private List<String> parseFields(value) {
        if( value == null )
            return DEF_FIELDS
        if( value instanceof CharSequence )
            return value.tokenize(',').collect(it -> it.trim())
        if( value instanceof List )
            return value
        throw new IllegalArgumentException("Not a valid trace fields value: $value")
    }

    static final String defaultFileName() {
        return "trace-${TraceHelper.launchTimestampFmt()}.txt"
    }

}
