/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * 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 com.android.tradefed.device.metric;

import com.android.ddmlib.NullOutputReceiver;
import com.android.tradefed.config.Option;
import com.android.tradefed.config.OptionClass;

import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.device.CollectingOutputReceiver;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.result.LogDataType;
import com.android.tradefed.log.LogUtil.CLog;

import java.util.concurrent.TimeUnit;

/**
 * A {@link IMetricCollector} that collects traces during the test using trace-cmd, and logs them to
 * the invocation.
 *
 * <p>This trace collector allows for USB disconnection during the test (as in power testing).
 *
 * <p>The system default tool, atrace, is used in tandem with this collector to set the
 * android-specific sysfs flags.
 *
 * <p>A trace-cmd (https://git.kernel.org/pub/scm/linux/kernel/git/rostedt/trace-cmd.git) binary
 * compatible with Android must be specified.
 *
 * <p>This will upload the trace.dat format (see man 5 trace-cmd.dat) produced by trace-cmd.
 */
@OptionClass(alias = "trace-cmd")
public class TraceCmdCollector extends AtraceCollector {
    /* Params for use of trace-cmd binary
     * The upstream tool, trace-cmd (https://git.kernel.org/pub/scm/linux/kernel/git/rostedt/trace-cmd.git)
     * will scrape the kernel buffers to disk at a configurable interval.
     * This is advantageous because:
     * 1) a packed format is produced, using less disk usage.
     * 2) no conversion of packed data to human-readable text occurs, resulting in less runtime
     *    processing overhead.
     * 3) an arbitrarily large file can be produced.
     * 4) wakeups can be scheduled at a large enough interval to minimize side-effects.
     *
     * Since its not a default system tool, a trace-cmd binary compatible with the target
     * device must be pushed to the device, and specified with --trace-cmd-binary
     */
    @Option(
        name = "trace-cmd-binary",
        description = "The path on the device of the trace-cmd binary to use"
    )
    private String mTraceCmdBinary = null;

    /* 'trace-cmd record' will be issued with these args.
     * the valid arguments are described in 'man 1 trace-cmd-record' (https://linux.die.net/man/1/trace-cmd-record)
     * The default is configured to wake up and spill to disk a 10s interval (-s), and use the boot clock.
     */
    @Option(
        name = "trace-cmd-recording-args",
        description = "The flags to pass to 'trace-cmd record'"
    )
    private String mTraceCmdRecordArgs =
            "-e sched:sched_waking "
                    + "-e sched:sched_wakeup -e sched:sched_wakeup_new "
                    + "-e sched:sched_switch -e power:cpu_idle "
                    + "-e power:cpu_frequency -e power:cpu_frequency_limits "
                    + "-e power:suspend_resume -e power:clock_set_rate "
                    + "-e power:clock_enable -e power:clock_disable "
                    + "-b 12000 -C boot -s 10000000 ";

    @Override
    protected LogDataType getLogType() {
        return LogDataType.KERNEL_TRACE;
    }

    @Override
    protected void startTracing(ITestDevice device) throws DeviceNotAvailableException {
        if (mTraceCmdBinary == null) {
            CLog.w("--trace-cmd-binary was not set, skipping trace metric collection");
            return;
        }
        /* trace-cmd will periodically scrape the kernel buffer to disk at a configurable rate.
         * No-raw-buffer -> human-readable-text will be performed by the kernel either.
         * The events set by atrace should still stay enabled.
         */
        super.startTracing(device);

        StringBuilder traceCmd = new StringBuilder(100);
        traceCmd.append("nohup ");
        traceCmd.append(mTraceCmdBinary);
        traceCmd.append(" record -o ");
        traceCmd.append(fullLogPath());
        traceCmd.append(" ");
        traceCmd.append(mTraceCmdRecordArgs);
        traceCmd.append(" > /dev/null 2>&1 &");
        CLog.i("Issuing trace-cmd: %s ", traceCmd.toString());
        CollectingOutputReceiver c = new CollectingOutputReceiver();
        device.executeShellCommand("chmod +x " + mTraceCmdBinary, c, 1, TimeUnit.SECONDS, 1);
        device.executeShellCommand(traceCmd.toString(), c, 1, TimeUnit.SECONDS, 1);
    }

    @Override
    protected void stopTracing(ITestDevice device) throws DeviceNotAvailableException {
        if (mTraceCmdBinary == null) {
            CLog.w("trace-cmd was not set, skipping attempt to stop trace collection");
            return;
        }

        // sigterm the trace process and monitor for the process's demise.
        // Failure to wait can result in a partial log being pulled.
        // Since it was started with nohup in a separate shell, trace-cmd is not a child
        // of this shell, and 'wait' won't work.
        CLog.i("Collecting trace-cmd log from device: " + device.getSerialNumber());
        device.executeShellCommand(
                "for PID in $(pidof trace-cmd); "
                        + "do while kill -s sigint $PID; do sleep 0.3; done; done;",
                new NullOutputReceiver(),
                60,
                TimeUnit.SECONDS,
                1);
    }
}
