"""Extract data for a specific date range from an SPK file."""

from sys import stderr
try:
    from urllib.request import URLopener
except:
    from urllib import URLopener

from numpy import copy
from .daf import DAF
from .spk import S_PER_DAY, T0

clip_lower = max
clip_upper = min

def _seconds(jd):
    """Convert a Julian Date to a number of seconds since J2000."""
    return (jd - T0) * S_PER_DAY

def write_excerpt(input_spk, output_file, start_jd, end_jd, summaries):
    start_seconds = _seconds(start_jd)
    end_seconds = _seconds(end_jd)
    old = input_spk.daf

    # Copy the file record and the comments verbatim.
    f = output_file
    f.seek(0)
    f.truncate()
    for n in range(1, old.fward):
        data = old.read_record(n)
        f.write(data)

    # Start an initial summary and name block.
    summary_data = b'\0' * 1024
    name_data = b' ' * 1024
    f.write(summary_data)
    f.write(name_data)

    d = DAF(f)
    d.fward = d.bward = old.fward
    d.free = (d.fward + 1) * (1024 // 8) + 1
    d.write_file_record()

    # Copy over an excerpt of each array.
    for name, values in summaries:
        start, end = values[-2], values[-1]
        init, intlen, rsize, n = old.read_array(end - 3, end)
        rsize = int(rsize)

        i = int(clip(0, n, (start_seconds - init) // intlen))
        j = int(clip(0, n, (end_seconds - init) // intlen + 1))
        if i == j:
            continue  # Segment has no overlap with user's dates.

        init = init + i * intlen
        n = j - i

        extra = 4     # enough room to rebuild [init intlen rsize n]
        excerpt = copy(old.read_array(
            start + rsize * i,
            start + rsize * j + extra - 1,
        ))
        excerpt[-4:] = (init, intlen, rsize, n)
        values = (init, init + n * intlen) + values[2:]
        d.add_array(b'X' + name[1:], values, excerpt)

def clip(lower, upper, n):
    return clip_lower(lower, clip_upper(upper, n))

class RemoteFile(object):
    def __init__(self, url):
        self.opener = URLopener()
        self.url = url
        self.filename = url.rstrip('/').rsplit('/', 1)[-1]
        self.offset = 0

    def seek(self, offset, whence=0):
        assert whence == 0
        self.offset = offset

    def read(self, size):
        start = self.offset
        end = start + size - 1
        assert end > start
        h = 'Range', 'bytes={}-{}'.format(start, end)
        stderr.write('Fetching {} {}\n'.format(self.filename, h[1]))
        self.opener.addheaders.append(h)
        data = self.opener.open(self.url).read()
        return data

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        pass
