///////////////////////////////////////////////////////////////////////////////
//
//  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 {

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

class FileUtility : public Utility
{
private:
    enum FileLongCode {
        LC_LIST = _LC_MAX,
        LC_OPTIMIZE,
        LC_DUMP,
    };

public:
    FileUtility( int, char** );

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

private:
    bool actionList     ( JobContext& );
    bool actionOptimize ( JobContext& );
    bool actionDump     ( JobContext& );

private:
    Group _actionGroup;

    bool (FileUtility::*_action)( JobContext& );
};

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

FileUtility::FileUtility( int argc, char** argv )
    : Utility      ( "mp4file", argc, argv )
    , _actionGroup ( "ACTIONS" )
    , _action      ( NULL )
{
    // add standard options which make sense for this utility
    _group.add( STD_DRYRUN );
    _group.add( STD_KEEPGOING );
    _group.add( STD_QUIET );
    _group.add( STD_DEBUG );
    _group.add( STD_VERBOSE );
    _group.add( STD_HELP );
    _group.add( STD_VERSION );
    _group.add( STD_VERSIONX );

    _actionGroup.add( "list",     false, LC_LIST,     "list (summary information)" );
    _actionGroup.add( "optimize", false, LC_OPTIMIZE, "optimize mp4 structure" );
    _actionGroup.add( "dump",     false, LC_DUMP,     "dump mp4 structure in human-readable format" );
    _groups.push_back( &_actionGroup );

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

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

bool
FileUtility::actionDump( 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() );

    if( !MP4Dump( job.fileHandle, _debugImplicits ))
        return herrf( "dump failed: %s\n", job.file.c_str() );

    return SUCCESS;
}

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

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

    const int wbrand = 5;
    const int wcompat = 18;
    const int wsizing = 6;
    const string sep = "  ";

    if( _jobCount == 0 ) {
      report << std::setw(wbrand) << left << "BRAND" << sep
             << std::setw(wcompat) << left << "COMPAT" << sep
             << std::setw(wsizing) << left << "SIZING" << 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() );

    FileSummaryInfo info;
    if( fileFetchSummaryInfo( job.fileHandle, info ))
        return herrf( "unable to fetch file summary info" );

    string compat;
    {
        const FileSummaryInfo::BrandSet::iterator ie = info.compatible_brands.end();
        int count = 0;
        for( FileSummaryInfo::BrandSet::iterator it = info.compatible_brands.begin(); it != ie; it++, count++ ) {
            if( count > 0 )
                compat += ',';
            compat += *it;
        }
    }

    const bool sizing = info.nlargesize | info.nversion1 | info.nspecial;

    report << std::setw(wbrand) << left << info.major_brand << sep
           << std::setw(wcompat) << left << compat << sep << std::setw(wsizing)
           << left << (sizing ? "64-bit" : "32-bit") << sep << job.file << '\n';

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

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

bool
FileUtility::actionOptimize( JobContext& job )
{
    verbose1f( "optimizing %s\n", job.file.c_str() );

    if( dryrunAbort() )
        return SUCCESS;

    if( !MP4Optimize( job.file.c_str(), NULL ))
        return herrf( "optimize failed: %s\n", job.file.c_str() );

    return SUCCESS;
}

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

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

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

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

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

    switch( code ) {
        case LC_LIST:
            _action = &FileUtility::actionList;
            break;

        case LC_OPTIMIZE:
            _action = &FileUtility::actionOptimize;
            break;

        case LC_DUMP:
            _action = &FileUtility::actionDump;
            break;

        default:
            handled = false;
            break;
    }

    return SUCCESS;
}

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

}} // namespace mp4v2::util

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

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