/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "aapt.h"

#include "command.h"
#include "print.h"
#include "util.h"

#include <regex>

const regex NS_REGEX("( *)N: ([^=]+)=(.*)");
const regex ELEMENT_REGEX("( *)E: ([^ ]+) \\(line=(\\d+)\\)");
const regex ATTR_REGEX("( *)A: ([^\\(=]+)[^=]*=\"([^\"]+)\".*");

const string ANDROID_NS("http://schemas.android.com/apk/res/android");

bool
Apk::HasActivity(const string& className)
{
    string fullClassName = full_class_name(package, className);
    const size_t N = activities.size();
    for (size_t i=0; i<N; i++) {
        if (activities[i] == fullClassName) {
            return true;
        }
    }
    return false;
}

struct Attribute {
    string ns;
    string name;
    string value;
};

struct Element {
    Element* parent;
    string ns;
    string name;
    int lineno;
    vector<Attribute> attributes;
    vector<Element*> children;

    /**
     * Indentation in the xmltree dump. Might not be equal to the distance
     * from the root because namespace rows (scopes) have their own indentation.
     */
    int depth;

    Element();
    ~Element();

    string GetAttr(const string& ns, const string& name) const;
    void FindElements(const string& ns, const string& name, vector<Element*>* result, bool recurse);
    
};

Element::Element()
{
}

Element::~Element()
{
    const size_t N = children.size();
    for (size_t i=0; i<N; i++) {
        delete children[i];
    }
}

string
Element::GetAttr(const string& ns, const string& name) const
{
    const size_t N = attributes.size();
    for (size_t i=0; i<N; i++) {
        const Attribute& attr = attributes[i];
        if (attr.ns == ns && attr.name == name) {
            return attr.value;
        }
    }
    return string();
}

void
Element::FindElements(const string& ns, const string& name, vector<Element*>* result, bool recurse)
{
    const size_t N = children.size();
    for (size_t i=0; i<N; i++) {
        Element* child = children[i];
        if (child->ns == ns && child->name == name) {
            result->push_back(child);
        }
        if (recurse) {
            child->FindElements(ns, name, result, recurse);
        }
    }
}

struct Scope {
    Scope* parent;
    int depth;
    map<string,string> namespaces;

    Scope(Scope* parent, int depth);
};

Scope::Scope(Scope* p, int d)
    :parent(p),
     depth(d)
{
     if (p != NULL) {
         namespaces = p->namespaces;
     }
}


string
full_class_name(const string& packageName, const string& className)
{
    if (className.length() == 0) {
        return "";
    }
    if (className[0] == '.') {
        return packageName + className;
    }
    if (className.find('.') == string::npos) {
        return packageName + "." + className;
    }
    return className;
}

string
pretty_component_name(const string& packageName, const string& className)
{
    if (starts_with(packageName, className)) {
        size_t pn = packageName.length();
        size_t cn = className.length();
        if (cn > pn && className[pn] == '.') {
            return packageName + "/" + string(className, pn, string::npos);
        }
    }
    return packageName + "/" + className;
}

int
inspect_apk(Apk* apk, const string& filename)
{
    // Load the manifest xml
    Command cmd("aapt2");
    cmd.AddArg("dump");
    cmd.AddArg("xmltree");
    cmd.AddArg(filename);
    cmd.AddArg("--file");
    cmd.AddArg("AndroidManifest.xml");

    int err;

    string output = get_command_output(cmd, &err, false);
    check_error(err);

    // Parse the manifest xml
    Scope* scope = new Scope(NULL, -1);
    Element* root = NULL;
    Element* current = NULL;
    vector<string> lines;
    split_lines(&lines, output);
    for (size_t i=0; i<lines.size(); i++) {
        const string& line = lines[i];
        smatch match;
        if (regex_match(line, match, NS_REGEX)) {
            int depth = match[1].length() / 2;
            while (depth < scope->depth) {
                Scope* tmp = scope;
                scope = scope->parent;
                delete tmp;
            }
            scope = new Scope(scope, depth);
            scope->namespaces[match[2]] = match[3];
        } else if (regex_match(line, match, ELEMENT_REGEX)) {
            Element* element = new Element();

            string str = match[2];
            size_t colon = str.find(':');
            if (colon == string::npos) {
                element->name = str;
            } else {
                element->ns = scope->namespaces[string(str, 0, colon)];
                element->name.assign(str, colon+1, string::npos);
            }
            element->lineno = atoi(match[3].str().c_str());
            element->depth = match[1].length() / 2;

            if (root == NULL) {
                current = element;
                root = element;
            } else {
                while (element->depth <= current->depth && current->parent != NULL) {
                    current = current->parent;
                }
                element->parent = current;
                current->children.push_back(element);
                current = element;
            }
        } else if (regex_match(line, match, ATTR_REGEX)) {
            if (current != NULL) {
                Attribute attr;
                string str = match[2];
                size_t colon = str.rfind(':');
                if (colon == string::npos) {
                    attr.name = str;
                } else {
                    attr.ns.assign(str, 0, colon);
                    attr.name.assign(str, colon+1, string::npos);
                }
                attr.value = match[3];
                current->attributes.push_back(attr);
            }
        }
    }
    while (scope != NULL) {
        Scope* tmp = scope;
        scope = scope->parent;
        delete tmp;
    }

    // Package name
    apk->package = root->GetAttr("", "package");
    if (apk->package.size() == 0) {
        print_error("%s:%d: Manifest root element doesn't contain a package attribute",
                filename.c_str(), root->lineno);
        delete root;
        return 1;
    }

    // Instrumentation runner
    vector<Element*> instrumentation;
    root->FindElements("", "instrumentation", &instrumentation, true);
    if (instrumentation.size() > 0) {
        // TODO: How could we deal with multiple instrumentation tags?
        // We'll just pick the first one.
        apk->runner = instrumentation[0]->GetAttr(ANDROID_NS, "name");
    }

    // Activities
    vector<Element*> activities;
    root->FindElements("", "activity", &activities, true);
    for (size_t i=0; i<activities.size(); i++) {
        string name = activities[i]->GetAttr(ANDROID_NS, "name");
        if (name.size() == 0) {
            continue;
        }
        apk->activities.push_back(full_class_name(apk->package, name));
    }

    delete root;
    return 0;
}

