package leigh.radio.rtlsdr;

import leigh.mecha.exec.LocalExecutor;
import leigh.mecha.exec.ProcessExecution;
import leigh.mecha.log.MechaLogger;
import leigh.mecha.log.MechaLoggerFactory;
import leigh.mecha.util.VelocityWatch;
import leigh.radio.Frequencies;

import java.io.DataInputStream;
import java.io.EOFException;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;

/**
 * Implementation of the {@link ADC} interface for the RTL2832 dongle which captures data using the
 * third-party <code>rtl_sdr</code> utility.
 *
 * @author Alex Leigh
 */
public class RtlSdr {
    private static final MechaLogger logger = MechaLoggerFactory.getLogger(RtlSdr.class);

    /**
     * Initiate an I/Q data capture on a locally connected RTL-SDR.
     */
    public void capture() throws Exception {
        ArrayList<String> args = new ArrayList<>();
        int sampleRate = 1000000;
        int samples = 1000000 * 60;

        //int samples = 1048600 * 10;

        args.add("-f " + Frequencies.MHZ_144);
        args.add("-n " + samples);
        args.add("-s " + sampleRate);
        args.add("-");

        logger.info("Executing rtl_sdr... [samples: {}] [rate: {}/s]", samples, sampleRate);

        LocalExecutor le = new LocalExecutor();
        ProcessExecution exec = le.execute("rtl_sdr", args);

        DataInputStream dis = new DataInputStream(exec.getInputStream());

        VelocityWatch vw = new VelocityWatch(logger);
        Instant firstSample=null;
        Instant lastSample;
        while (true) {
            try {
                if (firstSample == null) firstSample = Instant.now();
                int x = dis.readUnsignedShort();

                // TODO: Do something with the captured IQ value

                vw.event("symbol");
            } catch (EOFException e) {
                lastSample = Instant.now();
                break;
            }
        }
        vw.status();

        logger.info("SDR capture completed. [firstSample: {}] [duration: {}]", firstSample,
                Duration.between(firstSample, lastSample));
    }
}