/*
 * image_processor.h - 3a image processor
 *
 *  Copyright (c) 2014-2015 Intel Corporation
 *
 * 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.
 *
 * Author: Wind Yuan <feng.yuan@intel.com>
 */

#include "image_processor.h"
#include "xcam_thread.h"

namespace XCam {

void
ImageProcessCallback::process_buffer_done (ImageProcessor *processor, const SmartPtr<VideoBuffer> &buf) {
    XCAM_UNUSED (processor);
    XCAM_ASSERT (buf.ptr() && processor);

    int64_t ts = buf->get_timestamp();
    XCAM_UNUSED (ts);
    XCAM_LOG_DEBUG (
        "processor(%s) handled buffer(" XCAM_TIMESTAMP_FORMAT ") successfully",
        XCAM_STR(processor->get_name()),
        XCAM_TIMESTAMP_ARGS (ts));
}

void
ImageProcessCallback::process_buffer_failed (ImageProcessor *processor, const SmartPtr<VideoBuffer> &buf)
{
    XCAM_ASSERT (buf.ptr() && processor);

    int64_t ts = buf->get_timestamp();
    XCAM_UNUSED (ts);
    XCAM_LOG_WARNING (
        "processor(%s) handled buffer(" XCAM_TIMESTAMP_FORMAT ") failed",
        XCAM_STR(processor->get_name()),
        XCAM_TIMESTAMP_ARGS (ts));
}

void
ImageProcessCallback::process_image_result_done (ImageProcessor *processor, const SmartPtr<X3aResult> &result)
{
    XCAM_UNUSED (processor);
    XCAM_ASSERT (result.ptr() && processor);

    int64_t ts = result->get_timestamp();
    XCAM_UNUSED (ts);

    XCAM_LOG_DEBUG (
        "processor(%s) processed result(type:%d, timestamp:" XCAM_TIMESTAMP_FORMAT ") done",
        XCAM_STR(processor->get_name()),
        (int)result->get_type(),
        XCAM_TIMESTAMP_ARGS (ts));
}

class ImageProcessorThread
    : public Thread
{
public:
    ImageProcessorThread (ImageProcessor *processor)
        : Thread ("image_processor")
        , _processor (processor)
    {}
    ~ImageProcessorThread () {}

    virtual bool loop ();

private:
    ImageProcessor *_processor;
};

bool ImageProcessorThread::loop ()
{
    XCamReturn ret = _processor->buffer_process_loop ();
    if (ret == XCAM_RETURN_NO_ERROR || ret == XCAM_RETURN_ERROR_TIMEOUT)
        return true;
    return false;
}

class X3aResultsProcessThread
    : public Thread
{
    typedef SafeList<X3aResult> ResultQueue;
public:
    X3aResultsProcessThread (ImageProcessor *processor)
        : Thread ("x3a_results_process_thread")
        , _processor (processor)
    {}
    ~X3aResultsProcessThread () {}

    XCamReturn push_result (SmartPtr<X3aResult> &result) {
        _queue.push (result);
        return XCAM_RETURN_NO_ERROR;
    }

    void triger_stop () {
        _queue.pause_pop ();
    }

    virtual bool loop ();

private:
    ImageProcessor  *_processor;
    ResultQueue      _queue;
};

bool X3aResultsProcessThread::loop ()
{
    X3aResultList result_list;
    SmartPtr<X3aResult> result;

    result = _queue.pop (-1);
    if (!result.ptr ())
        return false;

    result_list.push_back (result);
    while ((result = _queue.pop (0)).ptr ()) {
        result_list.push_back (result);
    }

    XCamReturn ret = _processor->process_3a_results (result_list);
    if (ret != XCAM_RETURN_NO_ERROR) {
        XCAM_LOG_DEBUG ("processing 3a result failed");
    }

    return true;
}
ImageProcessor::ImageProcessor (const char* name)
    : _name (NULL)
    , _callback (NULL)
{
    if (name)
        _name = strndup (name, XCAM_MAX_STR_SIZE);

    _processor_thread = new ImageProcessorThread (this);
    _results_thread = new X3aResultsProcessThread (this);
}

ImageProcessor::~ImageProcessor ()
{
    if (_name)
        xcam_free (_name);
}

bool
ImageProcessor::set_callback (ImageProcessCallback *callback)
{
    XCAM_ASSERT (!_callback);
    _callback = callback;
    return true;
}

XCamReturn
ImageProcessor::start()
{
    XCamReturn ret = XCAM_RETURN_NO_ERROR;
    if (!_results_thread->start ()) {
        return XCAM_RETURN_ERROR_THREAD;
    }
    if (!_processor_thread->start ()) {
        return XCAM_RETURN_ERROR_THREAD;
    }
    ret = emit_start ();
    if (ret != XCAM_RETURN_NO_ERROR) {
        XCAM_LOG_WARNING ("ImageProcessor(%s) emit start failed", XCAM_STR (_name));
        _video_buf_queue.pause_pop ();
        _results_thread->triger_stop ();
        _processor_thread->stop ();
        _results_thread->stop ();
        return ret;
    }
    XCAM_LOG_INFO ("ImageProcessor(%s) started", XCAM_STR (_name));
    return XCAM_RETURN_NO_ERROR;
}

XCamReturn
ImageProcessor::stop()
{
    _video_buf_queue.pause_pop ();
    _results_thread->triger_stop ();

    emit_stop ();

    _processor_thread->stop ();
    _results_thread->stop ();
    XCAM_LOG_DEBUG ("ImageProcessor(%s) stopped", XCAM_STR (_name));
    return XCAM_RETURN_NO_ERROR;
}

XCamReturn
ImageProcessor::push_buffer (SmartPtr<VideoBuffer> &buf)
{
    if (_video_buf_queue.push (buf))
        return XCAM_RETURN_NO_ERROR;

    XCAM_LOG_DEBUG ("processor push buffer failed");
    return XCAM_RETURN_ERROR_UNKNOWN;
}

XCamReturn
ImageProcessor::push_3a_results (X3aResultList &results)
{
    XCAM_ASSERT (!results.empty ());
    XCamReturn ret = XCAM_RETURN_NO_ERROR;
    for (X3aResultList::iterator i_res = results.begin();
            i_res != results.end(); ++i_res) {
        SmartPtr<X3aResult> &res = *i_res;

        ret = _results_thread->push_result (res);
        if (ret != XCAM_RETURN_NO_ERROR)
            break;
    }

    XCAM_FAIL_RETURN(
        WARNING,
        ret == XCAM_RETURN_NO_ERROR,
        ret,
        "processor(%s) push 3a results failed", XCAM_STR(get_name()));
    return XCAM_RETURN_NO_ERROR;
}

XCamReturn
ImageProcessor::push_3a_result (SmartPtr<X3aResult> &result)
{
    XCamReturn ret = _results_thread->push_result (result);
    XCAM_FAIL_RETURN(
        WARNING,
        ret == XCAM_RETURN_NO_ERROR,
        ret,
        "processor(%s) push 3a result failed", XCAM_STR(get_name()));
    return XCAM_RETURN_NO_ERROR;
}

XCamReturn
ImageProcessor::process_3a_results (X3aResultList &results)
{
    X3aResultList valid_results;
    XCamReturn ret = XCAM_RETURN_NO_ERROR;

    filter_valid_results (results, valid_results);
    if (valid_results.empty())
        return XCAM_RETURN_BYPASS;

    ret = apply_3a_results (valid_results);

    if (ret != XCAM_RETURN_NO_ERROR && ret != XCAM_RETURN_BYPASS) {
        XCAM_LOG_WARNING ("processor(%s) apply results failed", XCAM_STR(get_name()));
        return ret;
    }

    if (_callback) {
        for (X3aResultList::iterator i_res = valid_results.begin();
                i_res != valid_results.end(); ++i_res) {
            SmartPtr<X3aResult> &res = *i_res;
            _callback->process_image_result_done (this, res);
        }
    }

    return ret;
}

XCamReturn
ImageProcessor::process_3a_result (SmartPtr<X3aResult> &result)
{
    X3aResultList valid_results;
    XCamReturn ret = XCAM_RETURN_NO_ERROR;

    if (!can_process_result(result))
        return XCAM_RETURN_BYPASS;

    ret = apply_3a_result (result);

    if (ret != XCAM_RETURN_NO_ERROR && ret != XCAM_RETURN_BYPASS) {
        XCAM_LOG_WARNING ("processor(%s) apply result failed", XCAM_STR(get_name()));
        return ret;
    }

    if (_callback) {
        _callback->process_image_result_done (this, result);
    }

    return ret;
}

void
ImageProcessor::filter_valid_results (X3aResultList &input, X3aResultList &valid_results)
{
    for (X3aResultList::iterator i_res = input.begin(); i_res != input.end(); ) {
        SmartPtr<X3aResult> &res = *i_res;
        if (can_process_result(res)) {
            valid_results.push_back (res);
            input.erase (i_res++);
        } else
            ++i_res;
    }
}

void
ImageProcessor::notify_process_buffer_done (const SmartPtr<VideoBuffer> &buf)
{
    if (_callback)
        _callback->process_buffer_done (this, buf);
}

void
ImageProcessor::notify_process_buffer_failed (const SmartPtr<VideoBuffer> &buf)
{
    if (_callback)
        _callback->process_buffer_failed (this, buf);
}

XCamReturn
ImageProcessor::buffer_process_loop ()
{
    XCamReturn ret = XCAM_RETURN_NO_ERROR;
    SmartPtr<VideoBuffer> new_buf;
    SmartPtr<VideoBuffer> buf = _video_buf_queue.pop();

    if (!buf.ptr())
        return XCAM_RETURN_ERROR_MEM;

    ret = this->process_buffer (buf, new_buf);
    if (ret < XCAM_RETURN_NO_ERROR) {
        XCAM_LOG_DEBUG ("processing buffer failed");
        notify_process_buffer_failed (buf);
        return ret;
    }

    if (new_buf.ptr ())
        notify_process_buffer_done (new_buf);

    return XCAM_RETURN_NO_ERROR;
}

XCamReturn
ImageProcessor::emit_start ()
{
    return XCAM_RETURN_NO_ERROR;
}

void
ImageProcessor::emit_stop ()
{
}

};
