package leigh.astro.wcstools;

import leigh.astro.catalog.CatalogObject;
import leigh.astro.unit.DegreesMinutesSeconds;
import leigh.astro.unit.HoursMinutesSeconds;
import leigh.astro.unit.SphericalCoordinate;
import leigh.mecha.exec.BatchTask;
import leigh.mecha.log.MechaLogger;
import leigh.mecha.log.MechaLoggerFactory;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * This implementation makes a basic assumption that the order of output lines from sky2xy is the same as the order
 * of input lines in the tmp file. If sky2xy were to output in a different order, the results would be undefined.
 *
 * @author Alex Leigh
 */
public class Sky2XYTask implements BatchTask {
    private static final MechaLogger logger = MechaLoggerFactory.getLogger(Sky2XYTask.class);
    private final File tmpFile = File.createTempFile("leigh-astro", "txt");
    private final List<CatalogObject> objs;
    private final ArrayList<CatalogObject> matched = new ArrayList<>();

    public Sky2XYTask(List<CatalogObject> objs) throws IOException {
        this.objs = objs;

        // Write the coordinates to our sky file
        BufferedOutputStream fos = new BufferedOutputStream(new FileOutputStream(tmpFile));
        for (CatalogObject obj : objs) {
            SphericalCoordinate coord = obj.getJ2000Coordinate();
            HoursMinutesSeconds hms = new HoursMinutesSeconds(coord.getX());
            DegreesMinutesSeconds dms = new DegreesMinutesSeconds(coord.getY());
            String s = hms.asString() + " " + dms.asString() + "\n";
            fos.write(s.getBytes());
        }
        fos.close();
    }

    /**
     * Return the temporary file containing the sky coordinates.
     */
    public File getTmpFile() {
        return tmpFile;
    }

    @Override
    public void writeScript(OutputStream os) throws IOException {
        // Intentionally Blank
    }

    @Override
    public void finished(String result) throws IOException {
        /*
         * 20.0:12.0:6.0 38.0:21.0:17.0 J2000 -> 2310.276 1720.798
         * 20.0:59.0:17.0 44.0:31.0:43.0 J2000 -> 25917.614 20265.029 (off image)
         * 3.0:9.0:39.0 7.0:50.0:46.0 J2000 ->    0.000    0.000 (offscale)
         */

        String[] lines = result.split("\n");
        logger.debug("Solution. [got: {}] [expected: {}]", lines.length, objs.size());

        if (lines.length != objs.size()) {
            logger.error("Bad solution: {}", result);
            return;
        }

        int i = 0;

        for (String line : lines) {
            String[] parts = line.split(" ");
            // Anything other than 6 is off-scale or off-image
            if (parts.length == 6) {
                logger.debug("match: {}", objs.get(i));
                matched.add(objs.get(i));
            }
            i++;
        }

    }

    public ArrayList<CatalogObject> getMatched() {
        return matched;
    }
}
