#include "DMWriteTask.h"

#include "DMUtil.h"
#include "SkColorPriv.h"
#include "SkCommonFlags.h"
#include "SkImageEncoder.h"
#include "SkMallocPixelRef.h"
#include "SkStream.h"
#include "SkString.h"

DEFINE_bool(writePngOnly, false, "If true, don't encode raw bitmap after .png data.  "
                                 "This means -r won't work, but skdiff will still work fine.");

namespace DM {

// Splits off the last N suffixes of name (splitting on _) and appends them to out.
// Returns the total number of characters consumed.
static int split_suffixes(int N, const char* name, SkTArray<SkString>* out) {
    SkTArray<SkString> split;
    SkStrSplit(name, "_", &split);
    int consumed = 0;
    for (int i = 0; i < N; i++) {
        // We're splitting off suffixes from the back to front.
        out->push_back(split[split.count()-i-1]);
        consumed += out->back().size() + 1;  // Add one for the _.
    }
    return consumed;
}

inline static SkString find_gm_name(const Task& parent, SkTArray<SkString>* suffixList) {
    const int suffixes = parent.depth() + 1;
    const SkString& name = parent.name();
    const int totalSuffixLength = split_suffixes(suffixes, name.c_str(), suffixList);
    return SkString(name.c_str(), name.size() - totalSuffixLength);
}

WriteTask::WriteTask(const Task& parent, SkBitmap bitmap)
    : CpuTask(parent)
    , fGmName(find_gm_name(parent, &fSuffixes))
    , fBitmap(bitmap)
    , fData(NULL)
    , fExtension(".png") {}

WriteTask::WriteTask(const Task& parent, SkData *data, const char* ext)
    : CpuTask(parent)
    , fGmName(find_gm_name(parent, &fSuffixes))
    , fData(SkRef(data))
    , fExtension(ext) {}

void WriteTask::makeDirOrFail(SkString dir) {
    if (!sk_mkdir(dir.c_str())) {
        this->fail();
    }
}

namespace {

// One file that first contains a .png of an SkBitmap, then its raw pixels.
// We use this custom format to avoid premultiplied/unpremultiplied pixel conversions.
struct PngAndRaw {
    static bool Encode(SkBitmap bitmap, const char* path) {
        SkFILEWStream stream(path);
        if (!stream.isValid()) {
            SkDebugf("Can't write %s.\n", path);
            return false;
        }

        // Write a PNG first for humans and other tools to look at.
        if (!SkImageEncoder::EncodeStream(&stream, bitmap, SkImageEncoder::kPNG_Type, 100)) {
            SkDebugf("Can't encode a PNG.\n");
            return false;
        }
        if (FLAGS_writePngOnly) {
            return true;
        }

        // Pad out so the raw pixels start 4-byte aligned.
        const uint32_t maxPadding = 0;
        const size_t pos = stream.bytesWritten();
        stream.write(&maxPadding, SkAlign4(pos) - pos);

        // Then write our secret raw pixels that only DM reads.
        SkAutoLockPixels lock(bitmap);
        return stream.write(bitmap.getPixels(), bitmap.getSize());
    }

    // This assumes bitmap already has allocated pixels of the correct size.
    static bool Decode(const char* path, SkImageInfo info, SkBitmap* bitmap) {
        SkAutoTUnref<SkData> data(SkData::NewFromFileName(path));
        if (!data) {
            SkDebugf("Can't read %s.\n", path);
            return false;
        }

        // The raw pixels are at the end of the file.  We'll skip the encoded PNG at the front.
        const size_t rowBytes = info.minRowBytes();  // Assume densely packed.
        const size_t bitmapBytes = info.getSafeSize(rowBytes);
        if (data->size() < bitmapBytes) {
            SkDebugf("%s is too small to contain the bitmap we're looking for.\n", path);
            return false;
        }

        const size_t offset = data->size() - bitmapBytes;
        SkAutoTUnref<SkData> subset(
                SkData::NewSubset(data, offset, bitmapBytes));
        SkAutoTUnref<SkPixelRef> pixels(
            SkMallocPixelRef::NewWithData(
                    info, rowBytes, NULL/*ctable*/, subset));
        SkASSERT(pixels);

        bitmap->setInfo(info, rowBytes);
        bitmap->setPixelRef(pixels);
        return true;
    }
};

// Does not take ownership of data.
bool save_data_to_file(const SkData* data, const char* path) {
    SkFILEWStream stream(path);
    if (!stream.isValid() || !stream.write(data->data(), data->size())) {
        SkDebugf("Can't write %s.\n", path);
        return false;
    }
    return true;
}

}  // namespace

void WriteTask::draw() {
    SkString dir(FLAGS_writePath[0]);
#if SK_BUILD_FOR_IOS
    if (dir.equals("@")) {
        dir.set(FLAGS_resourcePath[0]);
    }
#endif
    this->makeDirOrFail(dir);
    for (int i = 0; i < fSuffixes.count(); i++) {
        dir = SkOSPath::Join(dir.c_str(), fSuffixes[i].c_str());
        this->makeDirOrFail(dir);
    }

    SkString path = SkOSPath::Join(dir.c_str(), fGmName.c_str());
    path.append(fExtension);

    const bool ok = fData.get() ? save_data_to_file(fData,   path.c_str())
                                : PngAndRaw::Encode(fBitmap, path.c_str());
    if (!ok) {
        this->fail();
    }
}

SkString WriteTask::name() const {
    SkString name("writing ");
    for (int i = 0; i < fSuffixes.count(); i++) {
        name.appendf("%s/", fSuffixes[i].c_str());
    }
    name.append(fGmName.c_str());
    return name;
}

bool WriteTask::shouldSkip() const {
    return FLAGS_writePath.isEmpty();
}

static SkString path_to_expected_image(const char* root, const Task& task) {
    SkString filename = task.name();

    // We know that all names passed in here belong to top-level Tasks, which have a single suffix
    // (8888, 565, gpu, etc.) indicating what subdirectory to look in.
    SkTArray<SkString> suffixes;
    const int suffixLength = split_suffixes(1, filename.c_str(), &suffixes);
    SkASSERT(1 == suffixes.count());

    // We'll look in root/suffix for images.
    const SkString dir = SkOSPath::Join(root, suffixes[0].c_str());

    // Remove the suffix and tack on a .png.
    filename.remove(filename.size() - suffixLength, suffixLength);
    filename.append(".png");

    return SkOSPath::Join(dir.c_str(), filename.c_str());
}

bool WriteTask::Expectations::check(const Task& task, SkBitmap bitmap) const {
    if (!FLAGS_writePath.isEmpty() && 0 == strcmp(FLAGS_writePath[0], fRoot)) {
        SkDebugf("We seem to be reading and writing %s concurrently.  This won't work.\n", fRoot);
        return false;
    }

    const SkString path = path_to_expected_image(fRoot, task);
    SkBitmap expected;
    if (!PngAndRaw::Decode(path.c_str(), bitmap.info(), &expected)) {
        return false;
    }

    return BitmapsEqual(expected, bitmap);
}

}  // namespace DM
