/*
 * Copyright (C) 2015 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.tv.tuner.source;

import android.content.Context;
import android.os.Environment;
import android.util.Log;
import android.util.SparseBooleanArray;

import com.google.android.exoplayer.C;
import com.google.android.exoplayer.upstream.DataSpec;
import com.android.tv.Features;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.tuner.ChannelScanFileParser.ScanChannel;
import com.android.tv.tuner.data.TunerChannel;
import com.android.tv.tuner.ts.TsParser;
import com.android.tv.tuner.tvinput.EventDetector;
import com.android.tv.tuner.tvinput.FileSourceEventDetector;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;

/**
 * Provides MPEG-2 TS stream sources for both channel scanning and channel playing from a local file
 * generated by capturing TV signal.
 */
public class FileTsStreamer implements TsStreamer {
    private static final String TAG = "FileTsStreamer";

    private static final int TS_PACKET_SIZE = 188;
    private static final int TS_SYNC_BYTE = 0x47;
    private static final int MIN_READ_UNIT = TS_PACKET_SIZE * 10;
    private static final int READ_BUFFER_SIZE = MIN_READ_UNIT * 10; // ~20KB
    private static final int CIRCULAR_BUFFER_SIZE = MIN_READ_UNIT * 4000; // ~ 8MB
    private static final int PADDING_SIZE = MIN_READ_UNIT * 1000; // ~2MB
    private static final int READ_TIMEOUT_MS = 10000; // 10 secs.
    private static final int BUFFER_UNDERRUN_SLEEP_MS = 10;
    private static final String FILE_DIR =
            new File(Environment.getExternalStorageDirectory(), "Streams").getAbsolutePath();

    // Virtual frequency base used for file-based source
    public static final int FREQ_BASE = 100;

    private final Object mCircularBufferMonitor = new Object();
    private final byte[] mCircularBuffer = new byte[CIRCULAR_BUFFER_SIZE];
    private final FileSourceEventDetector mEventDetector;
    private final Context mContext;

    private long mBytesFetched;
    private long mLastReadPosition;
    private boolean mStreaming;

    private Thread mStreamingThread;
    private StreamProvider mSource;

    public static class FileDataSource extends TsDataSource {
        private final FileTsStreamer mTsStreamer;
        private final AtomicLong mLastReadPosition = new AtomicLong(0);
        private long mStartBufferedPosition;

        private FileDataSource(FileTsStreamer tsStreamer) {
            mTsStreamer = tsStreamer;
            mStartBufferedPosition = tsStreamer.getBufferedPosition();
        }

        @Override
        public long getBufferedPosition() {
            return mTsStreamer.getBufferedPosition() - mStartBufferedPosition;
        }

        @Override
        public long getLastReadPosition() {
            return mLastReadPosition.get();
        }

        @Override
        public void shiftStartPosition(long offset) {
            SoftPreconditions.checkState(mLastReadPosition.get() == 0);
            SoftPreconditions.checkArgument(0 <= offset && offset <= getBufferedPosition());
            mStartBufferedPosition += offset;
        }

        @Override
        public long open(DataSpec dataSpec) throws IOException {
            mLastReadPosition.set(0);
            return C.LENGTH_UNBOUNDED;
        }

        @Override
        public void close() {
        }

        @Override
        public int read(byte[] buffer, int offset, int readLength) throws IOException {
            int ret = mTsStreamer.readAt(mStartBufferedPosition + mLastReadPosition.get(), buffer,
                    offset, readLength);
            if (ret > 0) {
                mLastReadPosition.addAndGet(ret);
            }
            return ret;
        }
    }

    /**
     * Creates {@link TsStreamer} for scanning & playing MPEG-2 TS file.
     * @param eventListener the listener for channel & program information
     */
    public FileTsStreamer(EventDetector.EventListener eventListener, Context context) {
        mEventDetector =
                new FileSourceEventDetector(
                        eventListener, Features.ENABLE_FILE_DVB.isEnabled(context));
        mContext = context;
    }

    @Override
    public boolean startStream(ScanChannel channel) {
        String filepath = new File(FILE_DIR, channel.filename).getAbsolutePath();
        mSource = new StreamProvider(filepath);
        if (!mSource.isReady()) {
            return false;
        }
        mEventDetector.start(mSource, FileSourceEventDetector.ALL_PROGRAM_NUMBERS);
        mSource.addPidFilter(TsParser.PAT_PID);
        mSource.addPidFilter(TsParser.ATSC_SI_BASE_PID);
        if (Features.ENABLE_FILE_DVB.isEnabled(mContext)) {
            mSource.addPidFilter(TsParser.DVB_EIT_PID);
            mSource.addPidFilter(TsParser.DVB_SDT_PID);
        }
        synchronized (mCircularBufferMonitor) {
            if (mStreaming) {
                return true;
            }
            mStreaming = true;
        }

        mStreamingThread = new StreamingThread();
        mStreamingThread.start();
        Log.i(TAG, "Streaming started");
        return true;
    }

    @Override
    public boolean startStream(TunerChannel channel) {
        Log.i(TAG, "tuneToChannel with: " + channel.getFilepath());
        mSource = new StreamProvider(channel.getFilepath());
        if (!mSource.isReady()) {
            return false;
        }
        mEventDetector.start(mSource, channel.getProgramNumber());
        mSource.addPidFilter(channel.getVideoPid());
        for (Integer i : channel.getAudioPids()) {
            mSource.addPidFilter(i);
        }
        mSource.addPidFilter(channel.getPcrPid());
        mSource.addPidFilter(TsParser.PAT_PID);
        mSource.addPidFilter(TsParser.ATSC_SI_BASE_PID);
        if (Features.ENABLE_FILE_DVB.isEnabled(mContext)) {
            mSource.addPidFilter(TsParser.DVB_EIT_PID);
            mSource.addPidFilter(TsParser.DVB_SDT_PID);
        }
        synchronized (mCircularBufferMonitor) {
            if (mStreaming) {
                return true;
            }
            mStreaming = true;
        }

        mStreamingThread = new StreamingThread();
        mStreamingThread.start();
        Log.i(TAG, "Streaming started");
        return true;
    }

    /**
     * Blocks the current thread until the streaming thread stops. In rare cases when the tuner
     * device is overloaded this can take a while, but usually it returns pretty quickly.
     */
    @Override
    public void stopStream() {
        synchronized (mCircularBufferMonitor) {
            mStreaming = false;
            mCircularBufferMonitor.notify();
        }

        try {
            if (mStreamingThread != null) {
                mStreamingThread.join();
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    @Override
    public TsDataSource createDataSource() {
        return new FileDataSource(this);
    }

    /**
     * Returns the current buffered position from the file.
     * @return the current buffered position
     */
    public long getBufferedPosition() {
        synchronized (mCircularBufferMonitor) {
            return mBytesFetched;
        }
    }

    /**
     * Provides MPEG-2 transport stream from a local file. Stream can be filtered by PID.
     */
    public static class StreamProvider {
        private final String mFilepath;
        private final SparseBooleanArray mPids = new SparseBooleanArray();
        private final byte[] mPreBuffer = new byte[READ_BUFFER_SIZE];

        private BufferedInputStream mInputStream;

        private StreamProvider(String filepath) {
            mFilepath = filepath;
            open(filepath);
        }

        private void open(String filepath) {
            try {
                mInputStream = new BufferedInputStream(new FileInputStream(filepath));
            } catch (IOException e) {
                Log.e(TAG, "Error opening input stream", e);
                mInputStream = null;
            }
        }

        private boolean isReady() {
            return mInputStream != null;
        }

        /**
         * Returns the file path of the MPEG-2 TS file.
         */
        public String getFilepath() {
            return mFilepath;
        }

        /**
         * Adds a pid for filtering from the MPEG-2 TS file.
         */
        public void addPidFilter(int pid) {
            mPids.put(pid, true);
        }

        /**
         * Returns whether the current pid filter is empty or not.
         */
        public boolean isFilterEmpty() {
            return mPids.size() == 0;
        }

        /**
         * Clears the current pid filter.
         */
        public void clearPidFilter() {
            mPids.clear();
        }

        /**
         * Returns whether a pid is in the pid filter or not.
         * @param pid the pid to check
         */
        public boolean isInFilter(int pid) {
            return mPids.get(pid);
        }

        /**
         * Reads from the MPEG-2 TS file to buffer.
         *
         * @param inputBuffer to read
         * @return the number of read bytes
         */
        private int read(byte[] inputBuffer) {
            int readSize = readInternal();
            if (readSize <= 0) {
                // Reached the end of stream. Restart from the beginning.
                close();
                open(mFilepath);
                if (mInputStream == null) {
                    return -1;
                }
                readSize = readInternal();
            }

            if (mPreBuffer[0] != TS_SYNC_BYTE) {
                Log.e(TAG, "Error reading input stream - no TS sync found");
                return -1;
            }
            int filteredSize = 0;
            for (int i = 0, destPos = 0; i < readSize; i += TS_PACKET_SIZE) {
                if (mPreBuffer[i] == TS_SYNC_BYTE) {
                    int pid = ((mPreBuffer[i + 1] & 0x1f) << 8) + (mPreBuffer[i + 2] & 0xff);
                    if (mPids.get(pid)) {
                        System.arraycopy(mPreBuffer, i, inputBuffer, destPos, TS_PACKET_SIZE);
                        destPos += TS_PACKET_SIZE;
                        filteredSize += TS_PACKET_SIZE;
                    }
                }
            }
            return filteredSize;
        }

        private int readInternal() {
            int readSize;
            try {
                readSize = mInputStream.read(mPreBuffer, 0, mPreBuffer.length);
            } catch (IOException e) {
                Log.e(TAG, "Error reading input stream", e);
                return -1;
            }
            return readSize;
        }

        private void close() {
            try {
                mInputStream.close();
            } catch (IOException e) {
                Log.e(TAG, "Error closing input stream:", e);
            }
            mInputStream = null;
        }
    }

    /**
     * Reads data from internal buffer.
     * @param pos the position to read from
     * @param buffer to read
     * @param offset start position of the read buffer
     * @param amount number of bytes to read
     * @return number of read bytes when successful, {@code -1} otherwise
     * @throws IOException
     */
    public int readAt(long pos, byte[] buffer, int offset, int amount) throws IOException {
        synchronized (mCircularBufferMonitor) {
            long initialBytesFetched = mBytesFetched;
            while (mBytesFetched < pos + amount && mStreaming) {
                try {
                    mCircularBufferMonitor.wait(READ_TIMEOUT_MS);
                } catch (InterruptedException e) {
                    // Wait again.
                    Thread.currentThread().interrupt();
                }
                if (initialBytesFetched == mBytesFetched) {
                    Log.w(TAG, "No data update for " + READ_TIMEOUT_MS + "ms. returning -1.");

                    // Returning -1 will make demux report EOS so that the input service can retry
                    // the playback.
                    return -1;
                }
            }
            if (!mStreaming) {
                Log.w(TAG, "Stream is already stopped.");
                return -1;
            }
            if (mBytesFetched - CIRCULAR_BUFFER_SIZE > pos) {
                Log.e(TAG, "Demux is requesting the data which is already overwritten.");
                return -1;
            }
            int posInBuffer = (int) (pos % CIRCULAR_BUFFER_SIZE);
            int bytesToCopyInFirstPass = amount;
            if (posInBuffer + bytesToCopyInFirstPass > mCircularBuffer.length) {
                bytesToCopyInFirstPass = mCircularBuffer.length - posInBuffer;
            }
            System.arraycopy(mCircularBuffer, posInBuffer, buffer, offset, bytesToCopyInFirstPass);
            if (bytesToCopyInFirstPass < amount) {
                System.arraycopy(mCircularBuffer, 0, buffer, offset + bytesToCopyInFirstPass,
                        amount - bytesToCopyInFirstPass);
            }
            mLastReadPosition = pos + amount;
            mCircularBufferMonitor.notify();
            return amount;
        }
    }

    /**
     * Adds {@link ScanChannel} instance for local files.
     *
     * @param output a list of channels where the results will be placed in
     */
    public static void addLocalStreamFiles(List<ScanChannel> output) {
        File dir = new File(FILE_DIR);
        if (!dir.exists()) return;

        File[] tsFiles = dir.listFiles();
        if (tsFiles == null) return;
        int freq = FileTsStreamer.FREQ_BASE;
        for (File file : tsFiles) {
            if (!file.isFile()) continue;
            output.add(ScanChannel.forFile(freq, file.getName()));
            freq += 100;
        }
    }

    /**
     * A thread managing a circular buffer that holds stream data to be consumed by player.
     * Keeps reading data in from a {@link StreamProvider} to hold enough amount for buffering.
     * Started and stopped by {@link #startStream()} and {@link #stopStream()}, respectively.
     */
    private class StreamingThread extends Thread {
        @Override
        public void run() {
            byte[] dataBuffer = new byte[READ_BUFFER_SIZE];

            synchronized (mCircularBufferMonitor) {
                mBytesFetched = 0;
                mLastReadPosition = 0;
            }

            while (true) {
                synchronized (mCircularBufferMonitor) {
                    while ((mBytesFetched - mLastReadPosition + PADDING_SIZE) > CIRCULAR_BUFFER_SIZE
                            && mStreaming) {
                        try {
                            mCircularBufferMonitor.wait();
                        } catch (InterruptedException e) {
                            // Wait again.
                            Thread.currentThread().interrupt();
                        }
                    }
                    if (!mStreaming) {
                        break;
                    }
                }

                int bytesWritten = mSource.read(dataBuffer);
                if (bytesWritten <= 0) {
                    try {
                        // When buffer is underrun, we sleep for short time to prevent
                        // unnecessary CPU draining.
                        sleep(BUFFER_UNDERRUN_SLEEP_MS);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                    continue;
                }

                mEventDetector.feedTSStream(dataBuffer, 0, bytesWritten);

                synchronized (mCircularBufferMonitor) {
                    int posInBuffer = (int) (mBytesFetched % CIRCULAR_BUFFER_SIZE);
                    int bytesToCopyInFirstPass = bytesWritten;
                    if (posInBuffer + bytesToCopyInFirstPass > mCircularBuffer.length) {
                        bytesToCopyInFirstPass = mCircularBuffer.length - posInBuffer;
                    }
                    System.arraycopy(dataBuffer, 0, mCircularBuffer, posInBuffer,
                            bytesToCopyInFirstPass);
                    if (bytesToCopyInFirstPass < bytesWritten) {
                        System.arraycopy(dataBuffer, bytesToCopyInFirstPass, mCircularBuffer, 0,
                                bytesWritten - bytesToCopyInFirstPass);
                    }
                    mBytesFetched += bytesWritten;
                    mCircularBufferMonitor.notify();
                }
            }

            Log.i(TAG, "Streaming stopped");
            mSource.close();
        }
    }
}
