///////////////////////////////////////////////////////////////////////////////
//
//  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 {
        string         name;
        string         ext;
        std::vector<string> cwarns; // compatibility warnings
        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& );

    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 string sep = "  ";

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

        report << setfill('-') << setw(70) << "" << 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 << setw(widx) << right << i << sep << setw(wsize) << item.size
             << sep << setw(8) << setfill('0') << hex << crc << setfill(' ')
             << dec << sep << setw(wtype) << left
             << enumBasicType.toString(item.type);

      if (line++ == 0) report << sep << 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
    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();
}
