///////////////////////////////////////////////////////////////////////////////
//
//  The contents of this file are subject to the Mozilla Public License
//  Version 1.1 (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.mozilla.org/MPL/
//
//  Software distributed under the License is distributed on an "AS IS"
//  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
//  License for the specific language governing rights and limitations
//  under the License.
// 
//  The Original Code is MP4v2.
// 
//  The Initial Developer of the Original Code is Kona Blend.
//  Portions created by Kona Blend are Copyright (C) 2008.
//  Portions created by David Byron are Copyright (C) 2010.
//  All Rights Reserved.
//
//  Contributors:
//      Kona Blend, kona8lend@@gmail.com
//      David Byron, dbyron@dbyron.com
//
///////////////////////////////////////////////////////////////////////////////

#include "util/impl.h"

namespace mp4v2 { namespace util {
    using namespace itmf;

///////////////////////////////////////////////////////////////////////////////

class ArtUtility : public Utility
{
private:
    enum ArtLongCode {
        LC_ART_ANY = _LC_MAX,
        LC_ART_INDEX,
        LC_LIST,
        LC_ADD,
        LC_REMOVE,
        LC_REPLACE,
        LC_EXTRACT,
    };

public:
    ArtUtility( int, char** );

protected:
    // delegates implementation
    bool utility_option( int, bool& );
    bool utility_job( JobContext& );

private:
    struct ArtType {
        std::string         name;
        std::string         ext;
        std::vector<std::string> cwarns; // compatibility warnings
        std::string         cerror; // compatibility error
    };

    bool actionList    ( JobContext& );
    bool actionAdd     ( JobContext& );
    bool actionRemove  ( JobContext& );
    bool actionReplace ( JobContext& );
    bool actionExtract ( JobContext& );

    bool extractSingle( JobContext&, const CoverArtBox::Item&, uint32_t );

private:
    Group  _actionGroup;
    Group  _parmGroup;

    bool (ArtUtility::*_action)( JobContext& );

    std::string   _artImageFile;
    uint32_t _artFilter;
};

///////////////////////////////////////////////////////////////////////////////

ArtUtility::ArtUtility( int argc, char** argv )
    : Utility      ( "mp4art", argc, argv )
    , _actionGroup ( "ACTIONS" )
    , _parmGroup   ( "ACTION PARAMETERS" )
    , _action      ( NULL )
    , _artFilter   ( std::numeric_limits<uint32_t>::max() )
{
    // add standard options which make sense for this utility
    _group.add( STD_OPTIMIZE );
    _group.add( STD_DRYRUN );
    _group.add( STD_KEEPGOING );
    _group.add( STD_OVERWRITE );
    _group.add( STD_FORCE );
    _group.add( STD_QUIET );
    _group.add( STD_DEBUG );
    _group.add( STD_VERBOSE );
    _group.add( STD_HELP );
    _group.add( STD_VERSION );
    _group.add( STD_VERSIONX );

    _parmGroup.add( "art-any",   false, LC_ART_ANY,   "act on all covr-boxes (default)" );
    _parmGroup.add( "art-index", true,  LC_ART_INDEX, "act on covr-box index IDX", "IDX" );
    _groups.push_back( &_parmGroup );

    _actionGroup.add( "list",    false, LC_LIST,    "list all covr-boxes" );
    _actionGroup.add( "add",     true,  LC_ADD,     "add covr-box from IMG file", "IMG" );
    _actionGroup.add( "replace", true,  LC_REPLACE, "replace covr-box with IMG file", "IMG" );
    _actionGroup.add( "remove",  false, LC_REMOVE,  "remove covr-box" );
    _actionGroup.add( "extract", false, LC_EXTRACT, "extract covr-box" );
    _groups.push_back( &_actionGroup );

    _usage = "[OPTION]... ACTION file...";
    _description =
        // 79-cols, inclusive, max desired width
        // |----------------------------------------------------------------------------|
        "\nFor each mp4 (m4a) file specified, perform the specified ACTION. An action"
        "\nmust be specified. Some options are not applicable for some actions.";
}

///////////////////////////////////////////////////////////////////////////////

bool
ArtUtility::actionAdd( JobContext& job )
{
    File in( _artImageFile, File::MODE_READ );
    if( in.open() )
        return herrf( "unable to open %s for read: %s\n", _artImageFile.c_str(), sys::getLastErrorStr() );

    const uint32_t max = std::numeric_limits<uint32_t>::max();
    if( in.size > max )
        return herrf( "file too large: %s (exceeds %u bytes)\n", _artImageFile.c_str(), max );

    CoverArtBox::Item item;
    item.size     = static_cast<uint32_t>( in.size );
    item.buffer   = static_cast<uint8_t*>( malloc( item.size ));
    item.autofree = true;

    File::Size nin;
    if( in.read( item.buffer, item.size, nin ))
        return herrf( "read failed: %s\n", _artImageFile.c_str() );

    in.close();

    verbose1f( "adding %s -> %s\n", _artImageFile.c_str(), job.file.c_str() );
    if( dryrunAbort() )
        return SUCCESS;

    job.fileHandle = MP4Modify( job.file.c_str() );
    if( job.fileHandle == MP4_INVALID_FILE_HANDLE )
        return herrf( "unable to open for write: %s\n", job.file.c_str() );

    if( CoverArtBox::add( job.fileHandle, item ))
        return herrf( "unable to add covr-box\n" );

    return SUCCESS;
}

///////////////////////////////////////////////////////////////////////////////

bool
ArtUtility::actionExtract( JobContext& job )
{
    job.fileHandle = MP4Read( job.file.c_str() );
    if( job.fileHandle == MP4_INVALID_FILE_HANDLE )
        return herrf( "unable to open for read: %s\n", job.file.c_str() );

    // single-mode
    if( _artFilter != std::numeric_limits<uint32_t>::max() ) {
        CoverArtBox::Item item;
        if( CoverArtBox::get( job.fileHandle, item, _artFilter ))
            return herrf( "unable to retrieve covr-box (index=%d): %s\n", _artFilter, job.file.c_str() );

        return extractSingle( job, item, _artFilter );
    }

    // wildcard-mode
    CoverArtBox::ItemList items;
    if( CoverArtBox::list( job.fileHandle, items ))
        return herrf( "unable to fetch list of covr-box: %s\n", job.file.c_str() );

    bool onesuccess = false;
    const CoverArtBox::ItemList::size_type max = items.size();
    for( CoverArtBox::ItemList::size_type i = 0; i < max; i++ ) {
        bool rv = extractSingle( job, items[i], (uint32_t)i );
        if( !rv )
            onesuccess = true;
        if( !_keepgoing && rv )
            return FAILURE;
    }

    return _keepgoing ? onesuccess : SUCCESS;
}

///////////////////////////////////////////////////////////////////////////////

bool
ArtUtility::actionList( JobContext& job )
{
    ostringstream report;

    const int widx = 3;
    const int wsize = 8;
    const int wtype = 9;
    const std::string sep = "  ";

    if( _jobCount == 0 ) {
      report << std::setw(widx) << right << "IDX" << left << sep
             << std::setw(wsize) << right << "BYTES" << left << sep
             << std::setw(8) << "CRC32" << sep << std::setw(wtype) << "TYPE"
             << sep << std::setw(0) << "FILE" << '\n';

      report << std::setfill('-') << std::setw(70) << "" << std::setfill(' ')
             << '\n';
    }

    job.fileHandle = MP4Read( job.file.c_str() );
    if( job.fileHandle == MP4_INVALID_FILE_HANDLE )
        return herrf( "unable to open for read: %s\n", job.file.c_str() );

    CoverArtBox::ItemList items;
    if( CoverArtBox::list( job.fileHandle, items ))
        return herrf( "unable to get list of covr-box: %s\n", job.file.c_str() );

    int line = 0;
    const CoverArtBox::ItemList::size_type max = items.size();
    for( CoverArtBox::ItemList::size_type i = 0; i < max; i++ ) {
      if (_artFilter != std::numeric_limits<uint32_t>::max() && _artFilter != i)
        continue;

      CoverArtBox::Item& item = items[i];
      const uint32_t crc = crc32(item.buffer, item.size);

      report << std::setw(widx) << right << i << sep << std::setw(wsize)
             << item.size << sep << std::setw(8) << std::setfill('0')
             << std::hex << crc << std::setfill(' ') << std::dec << sep
             << std::setw(wtype) << left << enumBasicType.toString(item.type);

      if (line++ == 0) report << sep << std::setw(0) << job.file;

      report << '\n';
    }

    verbose1f( "%s", report.str().c_str() );
    return SUCCESS;
}

///////////////////////////////////////////////////////////////////////////////

bool
ArtUtility::actionRemove( JobContext& job )
{
    job.fileHandle = MP4Modify( job.file.c_str() );
    if( job.fileHandle == MP4_INVALID_FILE_HANDLE )
        return herrf( "unable to open for write: %s\n", job.file.c_str() );

    if( _artFilter == std::numeric_limits<uint32_t>::max() )
        verbose1f( "removing covr-box (all) from %s\n", job.file.c_str() );
    else
        verbose1f( "removing covr-box (index=%d) from %s\n", _artFilter, job.file.c_str() );

    if( dryrunAbort() )
        return SUCCESS;

    if( CoverArtBox::remove( job.fileHandle, _artFilter ))
        return herrf( "remove failed\n" );

    return SUCCESS;
}

///////////////////////////////////////////////////////////////////////////////

bool
ArtUtility::actionReplace( JobContext& job )
{
    File in( _artImageFile, File::MODE_READ );
    if( in.open() )
        return herrf( "unable to open %s for read: %s\n", _artImageFile.c_str(), sys::getLastErrorStr() );

    const uint32_t max = std::numeric_limits<uint32_t>::max();
    if( in.size > max )
        return herrf( "file too large: %s (exceeds %u bytes)\n", _artImageFile.c_str(), max );

    CoverArtBox::Item item;
    item.size     = static_cast<uint32_t>( in.size );
    item.buffer   = static_cast<uint8_t*>( malloc( item.size ));
    item.autofree = true;

    File::Size nin;
    if( in.read( item.buffer, item.size, nin ))
        return herrf( "read failed: %s\n", _artImageFile.c_str() );

    in.close();

    if( _artFilter == std::numeric_limits<uint32_t>::max() )
        verbose1f( "replacing %s -> %s (all)\n", _artImageFile.c_str(), job.file.c_str() );
    else
        verbose1f( "replacing %s -> %s (index=%d)\n", _artImageFile.c_str(), job.file.c_str(), _artFilter );

    if( dryrunAbort() )
        return SUCCESS;

    job.fileHandle = MP4Modify( job.file.c_str() );
    if( job.fileHandle == MP4_INVALID_FILE_HANDLE )
        return herrf( "unable to open for write: %s\n", job.file.c_str() );

    if( CoverArtBox::set( job.fileHandle, item, _artFilter ))
        return herrf( "unable to add covr-box: %s\n", job.file.c_str() );

    return SUCCESS;
}

///////////////////////////////////////////////////////////////////////////////

bool
ArtUtility::extractSingle( JobContext& job, const CoverArtBox::Item& item, uint32_t index )
{
    // compute out filename
    std::string out_name = job.file;
    FileSystem::pathnameStripExtension( out_name );

    ostringstream oss;
    oss << out_name << ".art[" << index << ']';

    // if implicit we try to determine type by inspecting data
    BasicType bt = item.type;
    if( bt == BT_IMPLICIT )
        bt = computeBasicType( item.buffer, item.size );

    // add file extension appropriate for known covr-box types
    switch( bt ) {
        case BT_GIF:    oss << ".gif"; break;
        case BT_JPEG:   oss << ".jpg"; break;
        case BT_PNG:    oss << ".png"; break;
        case BT_BMP:    oss << ".bmp"; break;

        default:
            oss << ".dat";
            break;
    }

    out_name = oss.str();
    verbose1f( "extracting %s (index=%d) -> %s\n", job.file.c_str(), index, out_name.c_str() );
    if( dryrunAbort() )
        return SUCCESS;

    File out( out_name, File::MODE_CREATE );
    if( openFileForWriting( out ))
        return FAILURE;

    File::Size nout;
    if( out.write( item.buffer, item.size, nout ))
        return herrf( "write failed: %s\n", out_name.c_str() );

    out.close();
    return SUCCESS;
}

///////////////////////////////////////////////////////////////////////////////

bool
ArtUtility::utility_job( JobContext& job )
{
    if( !_action )
        return herrf( "no action specified\n" );

    return (this->*_action)( job );
}

///////////////////////////////////////////////////////////////////////////////

bool
ArtUtility::utility_option( int code, bool& handled )
{
    handled = true;

    switch( code ) {
        case LC_ART_ANY:
            _artFilter = std::numeric_limits<uint32_t>::max();
            break;

        case LC_ART_INDEX:
        {
            istringstream iss( prog::optarg );
            iss >> _artFilter;
            if( iss.rdstate() != ios::eofbit )
                return herrf( "invalid cover-art index: %s\n", prog::optarg );
            break;
        }

        case LC_LIST:
            _action = &ArtUtility::actionList;
            break;

        case LC_ADD:
            _action = &ArtUtility::actionAdd;
            _artImageFile = prog::optarg;
            if( _artImageFile.empty() )
                return herrf( "invalid image file: empty-string\n" );
            break;

        case LC_REMOVE:
            _action = &ArtUtility::actionRemove;
            break;

        case LC_REPLACE:
            _action = &ArtUtility::actionReplace;
            _artImageFile = prog::optarg;
            if( _artImageFile.empty() )
                return herrf( "invalid image file: empty-string\n" );
            break;

        case LC_EXTRACT:
            _action = &ArtUtility::actionExtract;
            break;

        default:
            handled = false;
            break;
    }

    return SUCCESS;
}

///////////////////////////////////////////////////////////////////////////////

}} // namespace mp4v2::util

///////////////////////////////////////////////////////////////////////////////

extern "C"
int main( int argc, char** argv )
{
    mp4v2::util::ArtUtility util( argc, argv );
    return util.process();
}
