// Copyright (c) 2012 The WebM project authors. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS.  All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <map>
#include <memory>
#include <string>
#include <utility>

#include "mkvparser/mkvparser.h"
#include "mkvparser/mkvreader.h"
#include "webvtt/webvttparser.h"

using std::string;

// disable deprecation warnings for auto_ptr
#if defined(__GNUC__) && __GNUC__ >= 5
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif

namespace libwebm {
namespace vttdemux {

typedef long long mkvtime_t;  // NOLINT
typedef long long mkvpos_t;  // NOLINT
typedef std::auto_ptr<mkvparser::Segment> segment_ptr_t;

// WebVTT metadata tracks have a type (encoded in the CodecID for the track).
// We use |type| to synthesize a filename for the out-of-band WebVTT |file|.
struct MetadataInfo {
  enum Type { kSubtitles, kCaptions, kDescriptions, kMetadata, kChapters } type;
  FILE* file;
};

// We use a map, indexed by track number, to collect information about
// each track in the input file.
typedef std::map<long, MetadataInfo> metadata_map_t;  // NOLINT

// The distinguished key value we use to store the chapters
// information in the metadata map.
enum { kChaptersKey = 0 };

// The data from the original WebVTT Cue is stored as a WebM block.
// The FrameParser is used to parse the lines of text out from the
// block, in order to reconstruct the original WebVTT Cue.
class FrameParser : public libwebvtt::LineReader {
 public:
  //  Bind the FrameParser instance to a WebM block.
  explicit FrameParser(const mkvparser::BlockGroup* block_group);
  virtual ~FrameParser();

  // The Webm block (group) to which this instance is bound.  We
  // treat the payload of the block as a stream of characters.
  const mkvparser::BlockGroup* const block_group_;

 protected:
  // Read the next character from the character stream (the payload
  // of the WebM block).  We increment the stream pointer |pos_| as
  // each character from the stream is consumed.
  virtual int GetChar(char* c);

  // End-of-line handling requires that we put a character back into
  // the stream.  Here we need only decrement the stream pointer |pos_|
  // to unconsume the character.
  virtual void UngetChar(char c);

  // The current position in the character stream (the payload of the block).
  mkvpos_t pos_;

  // The position of the end of the character stream. When the current
  // position |pos_| equals the end position |pos_end_|, the entire
  // stream (block payload) has been consumed and end-of-stream is indicated.
  mkvpos_t pos_end_;

 private:
  // Disable copy ctor and copy assign
  FrameParser(const FrameParser&);
  FrameParser& operator=(const FrameParser&);
};

// The data from the original WebVTT Cue is stored as an MKV Chapters
// Atom element (the cue payload is stored as a Display sub-element).
// The ChapterAtomParser is used to parse the lines of text out from
// the String sub-element of the Display element (though it would be
// admittedly odd if there were more than one line).
class ChapterAtomParser : public libwebvtt::LineReader {
 public:
  explicit ChapterAtomParser(const mkvparser::Chapters::Display* display);
  virtual ~ChapterAtomParser();

  const mkvparser::Chapters::Display* const display_;

 protected:
  // Read the next character from the character stream (the title
  // member of the atom's display).  We increment the stream pointer
  // |str_| as each character from the stream is consumed.
  virtual int GetChar(char* c);

  // End-of-line handling requires that we put a character back into
  // the stream.  Here we need only decrement the stream pointer |str_|
  // to unconsume the character.
  virtual void UngetChar(char c);

  // The current position in the character stream (the title of the
  // atom's display).
  const char* str_;

  // The position of the end of the character stream. When the current
  // position |str_| equals the end position |str_end_|, the entire
  // stream (title of the display) has been consumed and end-of-stream
  // is indicated.
  const char* str_end_;

 private:
  ChapterAtomParser(const ChapterAtomParser&);
  ChapterAtomParser& operator=(const ChapterAtomParser&);
};

// Parse the EBML header of the WebM input file, to determine whether we
// actually have a WebM file.  Returns false if this is not a WebM file.
bool ParseHeader(mkvparser::IMkvReader* reader, mkvpos_t* pos);

// Parse the Segment of the input file and load all of its clusters.
// Returns false if there was an error parsing the file.
bool ParseSegment(mkvparser::IMkvReader* reader, mkvpos_t pos,
                  segment_ptr_t* segment);

// If |segment| has a Chapters element (in which case, there will be a
// corresponding entry in |metadata_map|), convert the MKV chapters to
// WebVTT chapter cues and write them to the output file.  Returns
// false on error.
bool WriteChaptersFile(const metadata_map_t& metadata_map,
                       const mkvparser::Segment* segment);

// Convert an MKV Chapters Atom to a WebVTT cue and write it to the
// output |file|.  Returns false on error.
bool WriteChaptersCue(FILE* file, const mkvparser::Chapters* chapters,
                      const mkvparser::Chapters::Atom* atom,
                      const mkvparser::Chapters::Display* display);

// Write the Cue Identifier line of the WebVTT cue, if it's present.
// Returns false on error.
bool WriteChaptersCueIdentifier(FILE* file,
                                const mkvparser::Chapters::Atom* atom);

// Use the timecodes from the chapters |atom| to write just the
// timings line of the WebVTT cue.  Returns false on error.
bool WriteChaptersCueTimings(FILE* file, const mkvparser::Chapters* chapters,
                             const mkvparser::Chapters::Atom* atom);

// Parse the String sub-element of the |display| and write the payload
// of the WebVTT cue.  Returns false on error.
bool WriteChaptersCuePayload(FILE* file,
                             const mkvparser::Chapters::Display* display);

// Iterate over the tracks of the input file (and any chapters
// element) and cache information about each metadata track.
void BuildMap(const mkvparser::Segment* segment, metadata_map_t* metadata_map);

// For each track listed in the cache, synthesize its output filename
// and open a file handle that designates the out-of-band file.
// Returns false if we were unable to open an output file for a track.
bool OpenFiles(metadata_map_t* metadata_map, const char* filename);

// Close the file handle for each track in the cache.
void CloseFiles(metadata_map_t* metadata_map);

// Iterate over the clusters of the input file, and write a WebVTT cue
// for each metadata block.  Returns false if processing of a cluster
// failed.
bool WriteFiles(const metadata_map_t& m, mkvparser::Segment* s);

// Write the WebVTT header for each track in the cache.  We do this
// immediately before writing the actual WebVTT cues.  Returns false
// if the write failed.
bool InitializeFiles(const metadata_map_t& metadata_map);

// Iterate over the blocks of the |cluster|, writing a WebVTT cue to
// its associated output file for each block of metadata.  Returns
// false if processing a block failed, or there was a parse error.
bool ProcessCluster(const metadata_map_t& metadata_map,
                    const mkvparser::Cluster* cluster);

// Look up this track number in the cache, and if found (meaning this
// is a metadata track), write a WebVTT cue to the associated output
// file.  Returns false if writing the WebVTT cue failed.
bool ProcessBlockEntry(const metadata_map_t& metadata_map,
                       const mkvparser::BlockEntry* block_entry);

// Parse the lines of text from the |block_group| to reconstruct the
// original WebVTT cue, and write it to the associated output |file|.
// Returns false if there was an error writing to the output file.
bool WriteCue(FILE* file, const mkvparser::BlockGroup* block_group);

// Consume a line of text from the character stream, and if the line
// is not empty write the cue identifier to the associated output
// file.  Returns false if there was an error writing to the file.
bool WriteCueIdentifier(FILE* f, FrameParser* parser);

// Consume a line of text from the character stream (which holds any
// cue settings) and write the cue timings line for this cue to the
// associated output file.  Returns false if there was an error
// writing to the file.
bool WriteCueTimings(FILE* f, FrameParser* parser);

// Write the timestamp (representating either the start time or stop
// time of the cue) to the output file.  Returns false if there was an
// error writing to the file.
bool WriteCueTime(FILE* f, mkvtime_t time_ns);

// Consume the remaining lines of text from the character stream
// (these lines are the actual payload of the WebVTT cue), and write
// them to the associated output file.  Returns false if there was an
// error writing to the file.
bool WriteCuePayload(FILE* f, FrameParser* parser);
}  // namespace vttdemux

namespace vttdemux {

FrameParser::FrameParser(const mkvparser::BlockGroup* block_group)
    : block_group_(block_group) {
  const mkvparser::Block* const block = block_group->GetBlock();
  const mkvparser::Block::Frame& f = block->GetFrame(0);

  // The beginning and end of the character stream corresponds to the
  // position of this block's frame within the WebM input file.

  pos_ = f.pos;
  pos_end_ = f.pos + f.len;
}

FrameParser::~FrameParser() {}

int FrameParser::GetChar(char* c) {
  if (pos_ >= pos_end_)  // end-of-stream
    return 1;  // per the semantics of libwebvtt::Reader::GetChar

  const mkvparser::Cluster* const cluster = block_group_->GetCluster();
  const mkvparser::Segment* const segment = cluster->m_pSegment;
  mkvparser::IMkvReader* const reader = segment->m_pReader;

  unsigned char* const buf = reinterpret_cast<unsigned char*>(c);
  const int result = reader->Read(pos_, 1, buf);

  if (result < 0)  // error
    return -1;

  ++pos_;  // consume this character in the stream
  return 0;
}

void FrameParser::UngetChar(char /* c */) {
  // All we need to do here is decrement the position in the stream.
  // The next time GetChar is called the same character will be
  // re-read from the input file.
  --pos_;
}

ChapterAtomParser::ChapterAtomParser(
    const mkvparser::Chapters::Display* display)
    : display_(display) {
  str_ = display->GetString();
  if (str_ == NULL)
    return;
  const size_t len = strlen(str_);
  str_end_ = str_ + len;
}

ChapterAtomParser::~ChapterAtomParser() {}

int ChapterAtomParser::GetChar(char* c) {
  if (str_ == NULL || str_ >= str_end_)  // end-of-stream
    return 1;  // per the semantics of libwebvtt::Reader::GetChar

  *c = *str_++;  // consume this character in the stream
  return 0;
}

void ChapterAtomParser::UngetChar(char /* c */) {
  // All we need to do here is decrement the position in the stream.
  // The next time GetChar is called the same character will be
  // re-read from the input file.
  --str_;
}

}  // namespace vttdemux

bool vttdemux::ParseHeader(mkvparser::IMkvReader* reader, mkvpos_t* pos) {
  mkvparser::EBMLHeader h;
  const mkvpos_t status = h.Parse(reader, *pos);

  if (status) {
    printf("error parsing EBML header\n");
    return false;
  }

  if (h.m_docType == NULL || strcmp(h.m_docType, "webm") != 0) {
    printf("bad doctype\n");
    return false;
  }

  return true;  // success
}

bool vttdemux::ParseSegment(mkvparser::IMkvReader* reader, mkvpos_t pos,
                            segment_ptr_t* segment_ptr) {
  // We first create the segment object.

  mkvparser::Segment* p;
  const mkvpos_t create = mkvparser::Segment::CreateInstance(reader, pos, p);

  if (create) {
    printf("error parsing segment element\n");
    return false;
  }

  segment_ptr->reset(p);

  // Now parse all of the segment's sub-elements, in toto.

  const long status = p->Load();  // NOLINT

  if (status < 0) {
    printf("error loading segment\n");
    return false;
  }

  return true;
}

void vttdemux::BuildMap(const mkvparser::Segment* segment,
                        metadata_map_t* map_ptr) {
  metadata_map_t& m = *map_ptr;
  m.clear();

  if (segment->GetChapters()) {
    MetadataInfo info;
    info.file = NULL;
    info.type = MetadataInfo::kChapters;

    m[kChaptersKey] = info;
  }

  const mkvparser::Tracks* const tt = segment->GetTracks();
  if (tt == NULL)
    return;

  const long tc = tt->GetTracksCount();  // NOLINT
  if (tc <= 0)
    return;

  // Iterate over the tracks in the intput file.  We determine whether
  // a track holds metadata by inspecting its CodecID.

  for (long idx = 0; idx < tc; ++idx) {  // NOLINT
    const mkvparser::Track* const t = tt->GetTrackByIndex(idx);

    if (t == NULL)  // weird
      continue;

    const long tn = t->GetNumber();  // NOLINT

    if (tn <= 0)  // weird
      continue;

    const char* const codec_id = t->GetCodecId();

    if (codec_id == NULL)  // weird
      continue;

    MetadataInfo info;
    info.file = NULL;

    if (strcmp(codec_id, "D_WEBVTT/SUBTITLES") == 0) {
      info.type = MetadataInfo::kSubtitles;
    } else if (strcmp(codec_id, "D_WEBVTT/CAPTIONS") == 0) {
      info.type = MetadataInfo::kCaptions;
    } else if (strcmp(codec_id, "D_WEBVTT/DESCRIPTIONS") == 0) {
      info.type = MetadataInfo::kDescriptions;
    } else if (strcmp(codec_id, "D_WEBVTT/METADATA") == 0) {
      info.type = MetadataInfo::kMetadata;
    } else {
      continue;
    }

    m[tn] = info;  // create an entry in the cache for this track
  }
}

bool vttdemux::OpenFiles(metadata_map_t* metadata_map, const char* filename) {
  if (metadata_map == NULL || metadata_map->empty())
    return false;

  if (filename == NULL)
    return false;

  // Find the position of the filename extension.  We synthesize the
  // output filename from the directory path and basename of the input
  // filename.

  const char* const ext = strrchr(filename, '.');

  if (ext == NULL)  // TODO(matthewjheaney): liberalize?
    return false;

  // Remember whether a track of this type has already been seen (the
  // map key) by keeping a count (the map item).  We quality the
  // output filename with the track number if there is more than one
  // track having a given type.

  std::map<MetadataInfo::Type, int> exists;

  typedef metadata_map_t::iterator iter_t;

  metadata_map_t& m = *metadata_map;
  const iter_t ii = m.begin();
  const iter_t j = m.end();

  // Make a first pass over the cache to determine whether there is
  // more than one track corresponding to a given metadata type.

  iter_t i = ii;
  while (i != j) {
    const metadata_map_t::value_type& v = *i++;
    const MetadataInfo& info = v.second;
    const MetadataInfo::Type type = info.type;
    ++exists[type];
  }

  // Make a second pass over the cache, synthesizing the filename of
  // each output file (from the input file basename, the input track
  // metadata type, and its track number if necessary), and then
  // opening a WebVTT output file having that filename.

  i = ii;
  while (i != j) {
    metadata_map_t::value_type& v = *i++;
    MetadataInfo& info = v.second;
    const MetadataInfo::Type type = info.type;

    // Start with the basename of the input file.

    string name(filename, ext);

    // Next append the metadata kind.

    switch (type) {
      case MetadataInfo::kSubtitles:
        name += "_SUBTITLES";
        break;

      case MetadataInfo::kCaptions:
        name += "_CAPTIONS";
        break;

      case MetadataInfo::kDescriptions:
        name += "_DESCRIPTIONS";
        break;

      case MetadataInfo::kMetadata:
        name += "_METADATA";
        break;

      case MetadataInfo::kChapters:
        name += "_CHAPTERS";
        break;

      default:
        return false;
    }

    // If there is more than one metadata track having a given type
    // (the WebVTT-in-WebM spec doesn't preclude this), then qualify
    // the output filename with the input track number.

    if (exists[type] > 1) {
      enum { kLen = 33 };
      char str[kLen];  // max 126 tracks, so only 4 chars really needed
#ifndef _MSC_VER
      snprintf(str, kLen, "%ld", v.first);  // track number
#else
      _snprintf_s(str, sizeof(str), kLen, "%ld", v.first);  // track number
#endif
      name += str;
    }

    // Finally append the output filename extension.

    name += ".vtt";

    // We have synthesized the full output filename, so attempt to
    // open the WebVTT output file.

    info.file = fopen(name.c_str(), "wb");
    const bool success = (info.file != NULL);

    if (!success) {
      printf("unable to open output file %s\n", name.c_str());
      return false;
    }
  }

  return true;
}

void vttdemux::CloseFiles(metadata_map_t* metadata_map) {
  if (metadata_map == NULL)
    return;

  metadata_map_t& m = *metadata_map;

  typedef metadata_map_t::iterator iter_t;

  iter_t i = m.begin();
  const iter_t j = m.end();

  // Gracefully close each output file, to ensure all output gets
  // propertly flushed.

  while (i != j) {
    metadata_map_t::value_type& v = *i++;
    MetadataInfo& info = v.second;

    if (info.file != NULL) {
      fclose(info.file);
      info.file = NULL;
    }
  }
}

bool vttdemux::WriteFiles(const metadata_map_t& m, mkvparser::Segment* s) {
  // First write the WebVTT header.

  InitializeFiles(m);

  if (!WriteChaptersFile(m, s))
    return false;

  // Now iterate over the clusters, writing the WebVTT cue as we parse
  // each metadata block.

  const mkvparser::Cluster* cluster = s->GetFirst();

  while (cluster != NULL && !cluster->EOS()) {
    if (!ProcessCluster(m, cluster))
      return false;

    cluster = s->GetNext(cluster);
  }

  return true;
}

bool vttdemux::InitializeFiles(const metadata_map_t& m) {
  // Write the WebVTT header for each output file in the cache.

  typedef metadata_map_t::const_iterator iter_t;
  iter_t i = m.begin();
  const iter_t j = m.end();

  while (i != j) {
    const metadata_map_t::value_type& v = *i++;
    const MetadataInfo& info = v.second;
    FILE* const f = info.file;

    if (fputs("WEBVTT\n", f) < 0) {
      printf("unable to initialize output file\n");
      return false;
    }
  }

  return true;
}

bool vttdemux::WriteChaptersFile(const metadata_map_t& m,
                                 const mkvparser::Segment* s) {
  const metadata_map_t::const_iterator info_iter = m.find(kChaptersKey);
  if (info_iter == m.end())  // no chapters, so nothing to do
    return true;

  const mkvparser::Chapters* const chapters = s->GetChapters();
  if (chapters == NULL)  // weird
    return true;

  const MetadataInfo& info = info_iter->second;
  FILE* const file = info.file;

  const int edition_count = chapters->GetEditionCount();

  if (edition_count <= 0)  // weird
    return true;  // nothing to do

  if (edition_count > 1) {
    // TODO(matthewjheaney): figure what to do here
    printf("more than one chapter edition detected\n");
    return false;
  }

  const mkvparser::Chapters::Edition* const edition = chapters->GetEdition(0);

  const int atom_count = edition->GetAtomCount();

  for (int idx = 0; idx < atom_count; ++idx) {
    const mkvparser::Chapters::Atom* const atom = edition->GetAtom(idx);
    const int display_count = atom->GetDisplayCount();

    if (display_count <= 0)
      continue;

    if (display_count > 1) {
      // TODO(matthewjheaney): handle case of multiple languages
      printf("more than 1 display in atom detected\n");
      return false;
    }

    const mkvparser::Chapters::Display* const display = atom->GetDisplay(0);

    if (const char* language = display->GetLanguage()) {
      if (strcmp(language, "eng") != 0) {
        // TODO(matthewjheaney): handle case of multiple languages.

        // We must create a separate webvtt file for each language.
        // This isn't a simple problem (which is why we defer it for
        // now), because there's nothing in the header that tells us
        // what languages we have as cues.  We must parse the displays
        // of each atom to determine that.

        // One solution is to make two passes over the input data.
        // First parse the displays, creating an in-memory cache of
        // all the chapter cues, sorted according to their language.
        // After we have read all of the chapter atoms from the input
        // file, we can then write separate output files for each
        // language.

        printf("only English-language chapter cues are supported\n");
        return false;
      }
    }

    if (!WriteChaptersCue(file, chapters, atom, display))
      return false;
  }

  return true;
}

bool vttdemux::WriteChaptersCue(FILE* f, const mkvparser::Chapters* chapters,
                                const mkvparser::Chapters::Atom* atom,
                                const mkvparser::Chapters::Display* display) {
  // We start a new cue by writing a cue separator (an empty line)
  // into the stream.

  if (fputc('\n', f) < 0)
    return false;

  // A WebVTT Cue comprises 3 things: a cue identifier, followed by
  // the cue timings, followed by the payload of the cue.  We write
  // each part of the cue in sequence.

  if (!WriteChaptersCueIdentifier(f, atom))
    return false;

  if (!WriteChaptersCueTimings(f, chapters, atom))
    return false;

  if (!WriteChaptersCuePayload(f, display))
    return false;

  return true;
}

bool vttdemux::WriteChaptersCueIdentifier(
    FILE* f, const mkvparser::Chapters::Atom* atom) {
  const char* const identifier = atom->GetStringUID();

  if (identifier == NULL)
    return true;  // nothing else to do

  if (fprintf(f, "%s\n", identifier) < 0)
    return false;

  return true;
}

bool vttdemux::WriteChaptersCueTimings(FILE* f,
                                       const mkvparser::Chapters* chapters,
                                       const mkvparser::Chapters::Atom* atom) {
  const mkvtime_t start_ns = atom->GetStartTime(chapters);

  if (start_ns < 0)
    return false;

  const mkvtime_t stop_ns = atom->GetStopTime(chapters);

  if (stop_ns < 0)
    return false;

  if (!WriteCueTime(f, start_ns))
    return false;

  if (fputs(" --> ", f) < 0)
    return false;

  if (!WriteCueTime(f, stop_ns))
    return false;

  if (fputc('\n', f) < 0)
    return false;

  return true;
}

bool vttdemux::WriteChaptersCuePayload(
    FILE* f, const mkvparser::Chapters::Display* display) {
  // Bind a Chapter parser object to the display, which allows us to
  // extract each line of text from the title-part of the display.
  ChapterAtomParser parser(display);

  int count = 0;  // count of lines of payload text written to output file
  for (string line;;) {
    const int e = parser.GetLine(&line);

    if (e < 0)  // error (only -- we allow EOS here)
      return false;

    if (line.empty())  // TODO(matthewjheaney): retain this check?
      break;

    if (fprintf(f, "%s\n", line.c_str()) < 0)
      return false;

    ++count;
  }

  if (count <= 0)  // WebVTT cue requires non-empty payload
    return false;

  return true;
}

bool vttdemux::ProcessCluster(const metadata_map_t& m,
                              const mkvparser::Cluster* c) {
  // Visit the blocks in this cluster, writing a WebVTT cue for each
  // metadata block.

  const mkvparser::BlockEntry* block_entry;

  long result = c->GetFirst(block_entry);  // NOLINT
  if (result < 0) {
    printf("bad cluster (unable to get first block)\n");
    return false;
  }

  while (block_entry != NULL && !block_entry->EOS()) {
    if (!ProcessBlockEntry(m, block_entry))
      return false;

    result = c->GetNext(block_entry, block_entry);
    if (result < 0) {  // error
      printf("bad cluster (unable to get next block)\n");
      return false;
    }
  }

  return true;
}

bool vttdemux::ProcessBlockEntry(const metadata_map_t& m,
                                 const mkvparser::BlockEntry* block_entry) {
  // If the track number for this block is in the cache, then we have
  // a metadata block, so write the WebVTT cue to the output file.

  const mkvparser::Block* const block = block_entry->GetBlock();
  const long long tn = block->GetTrackNumber();  // NOLINT

  typedef metadata_map_t::const_iterator iter_t;
  const iter_t i = m.find(static_cast<metadata_map_t::key_type>(tn));

  if (i == m.end())  // not a metadata track
    return true;  // nothing else to do

  if (block_entry->GetKind() != mkvparser::BlockEntry::kBlockGroup)
    return false;  // weird

  typedef mkvparser::BlockGroup BG;
  const BG* const block_group = static_cast<const BG*>(block_entry);

  const MetadataInfo& info = i->second;
  FILE* const f = info.file;

  return WriteCue(f, block_group);
}

bool vttdemux::WriteCue(FILE* f, const mkvparser::BlockGroup* block_group) {
  // Bind a FrameParser object to the block, which allows us to
  // extract each line of text from the payload of the block.
  FrameParser parser(block_group);

  // We start a new cue by writing a cue separator (an empty line)
  // into the stream.

  if (fputc('\n', f) < 0)
    return false;

  // A WebVTT Cue comprises 3 things: a cue identifier, followed by
  // the cue timings, followed by the payload of the cue.  We write
  // each part of the cue in sequence.

  if (!WriteCueIdentifier(f, &parser))
    return false;

  if (!WriteCueTimings(f, &parser))
    return false;

  if (!WriteCuePayload(f, &parser))
    return false;

  return true;
}

bool vttdemux::WriteCueIdentifier(FILE* f, FrameParser* parser) {
  string line;
  int e = parser->GetLine(&line);

  if (e)  // error or EOS
    return false;

  // If the cue identifier line is empty, this means that the original
  // WebVTT cue did not have a cue identifier, so we don't bother
  // writing an extra line terminator to the output file (though doing
  // so would be harmless).

  if (!line.empty()) {
    if (fputs(line.c_str(), f) < 0)
      return false;

    if (fputc('\n', f) < 0)
      return false;
  }

  return true;
}

bool vttdemux::WriteCueTimings(FILE* f, FrameParser* parser) {
  const mkvparser::BlockGroup* const block_group = parser->block_group_;
  const mkvparser::Cluster* const cluster = block_group->GetCluster();
  const mkvparser::Block* const block = block_group->GetBlock();

  // A WebVTT Cue "timings" line comprises two parts: the start and
  // stop time for this cue, followed by the (optional) cue settings,
  // such as orientation of the rendered text or its size.  Only the
  // settings part of the cue timings line is stored in the WebM
  // block.  We reconstruct the start and stop times of the WebVTT cue
  // from the timestamp and duration of the WebM block.

  const mkvtime_t start_ns = block->GetTime(cluster);

  if (!WriteCueTime(f, start_ns))
    return false;

  if (fputs(" --> ", f) < 0)
    return false;

  const mkvtime_t duration_timecode = block_group->GetDurationTimeCode();

  if (duration_timecode < 0)
    return false;

  const mkvparser::Segment* const segment = cluster->m_pSegment;
  const mkvparser::SegmentInfo* const info = segment->GetInfo();

  if (info == NULL)
    return false;

  const mkvtime_t timecode_scale = info->GetTimeCodeScale();

  if (timecode_scale <= 0)
    return false;

  const mkvtime_t duration_ns = duration_timecode * timecode_scale;
  const mkvtime_t stop_ns = start_ns + duration_ns;

  if (!WriteCueTime(f, stop_ns))
    return false;

  string line;
  int e = parser->GetLine(&line);

  if (e)  // error or EOS
    return false;

  if (!line.empty()) {
    if (fputc(' ', f) < 0)
      return false;

    if (fputs(line.c_str(), f) < 0)
      return false;
  }

  if (fputc('\n', f) < 0)
    return false;

  return true;
}

bool vttdemux::WriteCueTime(FILE* f, mkvtime_t time_ns) {
  mkvtime_t ms = time_ns / 1000000;  // WebVTT time has millisecond resolution

  mkvtime_t sec = ms / 1000;
  ms -= sec * 1000;

  mkvtime_t min = sec / 60;
  sec -= 60 * min;

  mkvtime_t hr = min / 60;
  min -= 60 * hr;

  if (hr > 0) {
    if (fprintf(f, "%02lld:", hr) < 0)
      return false;
  }

  if (fprintf(f, "%02lld:%02lld.%03lld", min, sec, ms) < 0)
    return false;

  return true;
}

bool vttdemux::WriteCuePayload(FILE* f, FrameParser* parser) {
  int count = 0;  // count of lines of payload text written to output file
  for (string line;;) {
    const int e = parser->GetLine(&line);

    if (e < 0)  // error (only -- we allow EOS here)
      return false;

    if (line.empty())  // TODO(matthewjheaney): retain this check?
      break;

    if (fprintf(f, "%s\n", line.c_str()) < 0)
      return false;

    ++count;
  }

  if (count <= 0)  // WebVTT cue requires non-empty payload
    return false;

  return true;
}

}  // namespace libwebm

int main(int argc, const char* argv[]) {
  if (argc != 2) {
    printf("usage: vttdemux <webmfile>\n");
    return EXIT_SUCCESS;
  }

  const char* const filename = argv[1];
  mkvparser::MkvReader reader;

  int e = reader.Open(filename);

  if (e) {  // error
    printf("unable to open file\n");
    return EXIT_FAILURE;
  }

  libwebm::vttdemux::mkvpos_t pos;

  if (!libwebm::vttdemux::ParseHeader(&reader, &pos))
    return EXIT_FAILURE;

  libwebm::vttdemux::segment_ptr_t segment_ptr;

  if (!libwebm::vttdemux::ParseSegment(&reader, pos, &segment_ptr))
    return EXIT_FAILURE;

  libwebm::vttdemux::metadata_map_t metadata_map;

  BuildMap(segment_ptr.get(), &metadata_map);

  if (metadata_map.empty()) {
    printf("no WebVTT metadata found\n");
    return EXIT_FAILURE;
  }

  if (!OpenFiles(&metadata_map, filename)) {
    CloseFiles(&metadata_map);  // nothing to flush, so not strictly necessary
    return EXIT_FAILURE;
  }

  if (!WriteFiles(metadata_map, segment_ptr.get())) {
    CloseFiles(&metadata_map);  // might as well flush what we do have
    return EXIT_FAILURE;
  }

  CloseFiles(&metadata_map);

  return EXIT_SUCCESS;
}
